I have a dataset like this:
{
_id: ObjectId("5b51a905c2ee6718204e945d"),
post: "hello apple"
},
{
_id: ObjectId("5b51a905c2ee6718204e945e"),
post: "he is going to buy a cup of coffee"
}
Now I would like to create a search, for that, I wrote the query i.e.
db.Collection.find({
post: { $regex: req.body.searchterm, $options: "i" }
}).then(data => {
console.log(data);
})
.catch(error => {
console.log(error)
});
This is working fine. Suppose I search "a" then it will return first and second object. But I want that result where a is individually written, not comes on between character.
I want only the second object return where a is written alone, but not comes on the first object because a is present on apple.
Any Suggestion on how I can enhance this. Any suggestion is really appreciated.
As Sergio suggested, use regex \ba\b. It will match only separate a
Regex online demo
try this :
var expression = new RegExp("(?=.*\\b" +req.body.searchterm + "\\b)")
db.Collection.find({
post: { $regex: expression, $options: "i" }
}).then(data => {
console.log(data);
})
.catch(error => {
console.log(error)
});
Related
I am trying to find 3 different field values while searching with .find() method and it gives either complete data or only one.
This is the code I have given:
const search = req.query.search || "";
const Rest = await Restaurant.find(
{name:{$regex:search,$options:"i"}},
{locality:{$regex:search,$options:'i'}},
{"cuisine.name":{$regex:search,$options:'i'})
I am getting an empty array as output, as I mentioned multiple fields together in .find()..
I am getting output if I use the below code(i.e) find only one field..
const Rest = await Restaurant.find({name:{$regex:search,$options:"i"}})
If I search for any of the 3 fields name/locality/cuisine.name I should get appropriate output.
Your original query was incorrect. Those conditions should be grouped into one parameter. It should be as below:
const Rest = await Restaurant.find({
name: {
$regex: search,
$options: "i"
},
locality: {
$regex: search,
$options: "i"
},
"cuisine.name": {
$regex: search,
$options: "i"
}
})
The above query will work the matching in AND conditions (all filter criteria must be fulfilled).
Instead, you need to work the query in OR conditions with the $or operator (either one of the filter criteria needed to be fulfilled).
Solution
const Rest = await Restaurant.find({
$or: [
{
name: {
$regex: search,
$options: "i"
}
},
{
locality: {
$regex: search,
$options: "i"
}
},
{
"cuisine.name": {
$regex: search,
$options: "i"
}
}
]
})
Demo # Mongo Playground
You can look at $and operator and $or operator in Mongodb, You can use $and operator if you want to match all of the given parameters or $or operator if one must match. Like this:
const Rest = await Restaurant.find({
$and: [
{ name: { $regex: search, $options: "i" } },
{ locality: { $regex: search, $options: "i" } },
{ "cuisine.name": { $regex: search, $options: "i" } },
],
});
See the documentation:
$and operator
$or operator
I am getting the following error
UnhandledPromiseRejectionWarning: MongoError: $regex has to be a
string
Below is my code:
let dbData = await client
.db('skreem-final')
.collection('influencers')
.countDocuments({
firstName: {
$regex: !/[~`!#$%\^&*+=\-\[\]\\';,/{}|\\":<>\?]/g,
$options: 'i',
},
});
// console.log(name, !/[~`!#$%\^&*+=\-\[\]\\';,/{}|\\":<>\?]/g.test(name));
console.log(dbData);
// });
Try enclosing your regex into " ":
$regex: "!/[~`!#$%\^&*+=\-\[\]\\';,/{}|\\":<>\?]/g",
Find items containing a whole word.
const queryparam = 'microsoft';
mongoose.model('tag').find({name: { $regex: new RegExp("\w"+queryparam+"\w" ), '$options': 'i' }});
// tag collection
[
{
name: 'Microsoft word" // this should be returned by query
},
{
name: 'Microsoft-word" // this should not be returned by query
}
]
It's not working.
Try this (thanks to #Toto):
db.tag.find({
name: {
"$regex": "\\bMicrosoft\\b\\s",
"$options": "i"
}
})
MongoPlayground
I try to build a test backend with express.
And got a problem that i cannot seem to overcome.
Trying to give the query object $regex param a value from the req.query.name. But it only returns an empty array. When i console.log(laptopName) it outputs the right value that is being given as a query param.
If i just replace $regex: laptopName with a concrete value $regex: 'vivobook' i do get results.
With $regex: laptopName console.log looks like this { name: { '$regex': '"vivobook"', '$options': 'i' } }
With $regex: 'vivobook' console.log looks like this: { name: { '$regex': 'vivobook', '$options': 'i' } }
app.get("/api/v1/laptops", (req, res) => {
MongoClient.connect(mongo_url, { useNewUrlParser: true }, (err, client) => {
const db = client.db("laptop_backend");
const collection = db.collection("laptops");
let laptopName = req.query.name;
let query = {
name: {
$regex: laptopName,
$options: 'i'
}
};
collection
.find(query)
.toArray()
.then(response => res.status(200).json(response))
.catch(err => console.error(err));
});
});
Try getting laptop name directly from params such as
let { name } = req.query;
let query = {
name: {
$regex: name,
$options: 'i',
}
};
if you are to modify completely i suggest changing code without promise.
app.get("/api/v1/laptops", async (req, res) => {
try {
const client = await MongoClient.connect(mongo_url, { useNewUrlParser: true });
const db = client.db('laptop_backend');
const collection = db.collection('laptops');
const { name } = req.query;
const query = {
name: {
$regex: name,
$options: 'i',
},
};
const result = await collection.find(query);
res.status(200).json({ result });
} catch (e) {
console.log(e);
res.status(400).json({ error: true });
}
});
Every thing work fine in this function, but this.nav.popToRoot() doesn't work in that location.
If I move it to the beginning of the function it works correctly.
Doesn't any one has a logical explanation for this.
Thank you in advance for your time and consideration.
Here is the code in a booking.ts component:
book(){
let newReservation = {
_id: this.room._id,
from: this.details.from.substring(0,10),
to: this.details.to.substring(0,10)
}
let loading = this.loadingCtrl.create({
content: "Booking room..."
});
loading.present();
this.roomsService.reserveRoom(newReservation).then((res) => {
loading.dismiss();
console.log("Room reserved successfully ... ");
this.nav.popToRoot();
}, (err) => {
console.log(err);
});
}
It happens the same to me, but i managed to replace the whole history stack, in my case after a certain point i don't need to keep the history stack, this is how i did it:
this.navCtrl.setPages([
{ page: RootPageHere }
]);
Works inside of a promise then function.