如果我有这个架构......
person = {
name : String,
favoriteFoods : Array
}
...其中favoriteFoods
数组填充了字符串。我怎样才能找到所有使用猫鼬“寿司”作为他们最喜欢的食物的人?
我希望有类似的东西:
PersonModel.find({ favoriteFoods : { $contains : "sushi" }, function(...) {...});
(我知道mongodb中没有$contains
,只是在了解解决方案之前解释我期待找到的内容)
由于favouriteFoods
是一个简单的字符串数组,您可以直接查询该字段:
PersonModel.find({ favouriteFoods: "sushi" }, ...);
但我还建议在模式中显式化字符串数组:
person = {
name : String,
favouriteFoods : [String]
}
相关文档可在此处找到:https://docs.mongodb.com/manual/tutorial/query-arrays/
我知道这个话题已经过时了,但是对于那些可能会想到同样问题的未来人来说,另一个非常低效的解决方案可能是:
PersonModel.find({$where : 'this.favouriteFoods.indexOf("sushi") != -1'});
这避免了MongoDB的所有优化,因此不要在生产代码中使用。
mongodb中没有$contains
操作符。
您可以使用JohnnyHK的答案。与mongo最接近的类比是$in
,使用此查询看起来像:
PersonModel.find({ favouriteFoods: { "$in" : ["sushi"]} }, ...);
在这种情况下,我觉得$all
会更合适。如果您正在寻找寿司的人,您可以:
PersonModel.find({ favoriteFood : { $all : ["sushi"] }, ...})
您可能希望过滤更多搜索,例如:
PersonModel.find({ favoriteFood : { $all : ["sushi", "bananas"] }, ...})
$in
就像OR和$all
一样喜欢AND。检查一下:https://docs.mongodb.com/manual/reference/operator/query/all/
如果数组包含对象,例如,如果favouriteFoods
是以下对象的数组:
{
name: 'Sushi',
type: 'Japanese'
}
您可以使用以下查询:
PersonModel.find({"favouriteFoods.name": "Sushi"});
如果你需要在子文档数组中找到包含NULL元素的文档,我发现这个查询非常有效:
db.collection.find({"keyWithArray":{$elemMatch:{"$in":[null], "$exists":true}}})
此查询来自这篇文章:MongoDb query array with null values
这是一个伟大的发现,它比我自己的初始和错误的版本(原来只适用于具有一个元素的数组)工作得更好:
.find({
'MyArrayOfSubDocuments': { $not: { $size: 0 } },
'MyArrayOfSubDocuments._id': { $exists: false }
})
虽然同意find()在您的用例中最有效。仍然存在聚合框架的$ match,以便于查询大量条目并生成少量结果,这些结果对您有价值,特别是对于分组和创建新文件。
PersonModel.aggregate([ { "$match": { $and : [{ 'favouriteFoods' : { $exists: true, $in: [ 'sushi']}}, ........ ] } }, { $project : {"_id": 0, "name" : 1} } ]);
包含lookup_food_array是数组。
match_stage["favoriteFoods"] = {'$elemMatch': {'$in': lookup_food_array}}
Incase of lookup_food_array是字符串。
match_stage["favoriteFoods"] = {'$elemMatch': lookup_food_string}
对于Loopback3,给出的所有示例对我来说都不起作用,或者与使用REST API一样快。但它帮助我找出了我需要的确切答案。
{"where":{"arrayAttribute":{ "all" :[String]}}}
如果你想通过javascript使用类似“包含”操作符的东西,你总是可以使用正则表达式...
例如。假设您要检索名为“Bartolomew”的客户
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);
}