可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
If I have this schema...
person = {
name : String,
favoriteFoods : Array
}
... where the favoriteFoods
array is populated with strings. How can I find all persons that have \"sushi\" as their favorite food using mongoose?
I was hoping for something along the lines of:
PersonModel.find({ favoriteFoods : { $contains : \"sushi\" }, function(...) {...});
(I know that there is no $contains
in mongodb, just explaining what I was expecting to find before knowing the solution)
回答1:
As favouriteFoods
is a simple array of strings, you can just query that field directly:
PersonModel.find({ favouriteFoods: \"sushi\" }, ...);
But I\'d also recommend making the string array explicit in your schema:
person = {
name : String,
favouriteFoods : [String]
}
回答2:
There is no $contains
operator in mongodb.
You can use the answer from JohnnyHK as that works. The closest analogy to contains that mongo has is $in
, using this your query would look like:
PersonModel.find({ favouriteFoods: { \"$in\" : [\"sushi\"]} }, ...);
回答3:
I feel like $all
would be more appropriate in this situation. If you are looking for person that is into sushi you do :
PersonModel.find({ favoriteFood : { $all : [\"sushi\"] }, ...})
As you might want to filter more your search, like so :
PersonModel.find({ favoriteFood : { $all : [\"sushi\", \"bananas\"] }, ...})
$in
is like OR and $all
like AND. Check this : https://docs.mongodb.com/manual/reference/operator/query/all/
回答4:
In case you need to find documents which contain NULL elements inside an array of sub-documents, I\'ve found this query which works pretty well:
db.collection.find({\"keyWithArray\":{$elemMatch:{\"$in\":[null], \"$exists\":true}}})
This query is taken from this post: MongoDb query array with null values
It was a great find and it works much better than my own initial and wrong version (which turned out to work fine only for arrays with one element):
.find({
\'MyArrayOfSubDocuments\': { $not: { $size: 0 } },
\'MyArrayOfSubDocuments._id\': { $exists: false }
})
回答5:
In case that the array contains objects for example if favouriteFoods
is an array of objects of the following:
{
name: \'Sushi\',
type: \'Japanese\'
}
you can use the following query:
PersonModel.find({\"favouriteFoods.name\": \"Sushi\"});
回答6:
For Loopback3 all the examples given did not work for me, or as fast as using REST API anyway. But it helped me to figure out the exact answer I needed.
{\"where\":{\"arrayAttribute\":{ \"all\" :[String]}}}
回答7:
Though agree with find() is most effective in your usecase. Still there is $match of aggregation framework, to ease the query of a big number of entries and generate a low number of results that hold value to you especially for grouping and creating new files.
PersonModel.aggregate([
{
\"$match\": {
$and : [{ \'favouriteFoods\' : { $exists: true, $in: [ \'sushi\']}}, ........ ] }
},
{ $project : {\"_id\": 0, \"name\" : 1} }
]);
回答8:
If you\'d want to use something like a \"contains\" operator through javascript, you can always use a Regular expression for that...
eg.
Say you want to retrieve a customer having \"Bartolomew\" as name
async function getBartolomew() {
const custStartWith_Bart = await Customers.find({name: /^Bart/ }); // Starts with Bart
const custEndWith_lomew = await Customers.find({name: /lomew$/ }); // Ends with lomew
const custContains_rtol = await Customers.find({name: /.*rtol.*/ }); // Contains rtol
console.log(custStartWith_Bart);
console.log(custEndWith_lomew);
console.log(custContains_rtol);
}
回答9:
I know this topic is old, but for future people who could wonder the same question, another incredibly inefficient solution could be to do:
PersonModel.find({$where : \'this.favouriteFoods.indexOf(\"sushi\") != -1\'});
This avoids all optimisations by MongoDB so do not use in production code.