查找包含特定值的数组的文档

Lud*_*son 456 mongoose mongodb

如果我有这个架构......

person = {
    name : String,
    favoriteFoods : Array
}
Run Code Online (Sandbox Code Playgroud)

... favoriteFoods数组中填充了字符串.我怎样才能找到所有使用猫鼬"寿司"作为他们最喜欢的食物的人?

我希望有类似的东西:

PersonModel.find({ favoriteFoods : { $contains : "sushi" }, function(...) {...});
Run Code Online (Sandbox Code Playgroud)

(我知道$contains在mongodb中没有,只是在了解解决方案之前解释我期望找到的内容)

Joh*_*yHK 636

作为favouriteFoods一个简单的字符串数组,您可以直接查询该字段:

PersonModel.find({ favouriteFoods: "sushi" }, ...);
Run Code Online (Sandbox Code Playgroud)

但我还建议在模式中显式化字符串数组:

person = {
    name : String,
    favouriteFoods : [String]
}
Run Code Online (Sandbox Code Playgroud)

  • 如果`favouriteFoods`是:'favouriteFoods:[{type:Schema.Types.ObjectId,ref:'Food'}],这也适用. (12认同)
  • 作为Mongo的新手来自像MySQL这样的RDBMS,发现这样的解决方案工作如此简单而不需要JOIN和其他表让我想知道为什么我没有尽快开始使用Mongo.但这并不是说DBMS优于另一个 - 这取决于您的用例. (10认同)
  • 别误会.即使它是一个dict列表,你仍然可以这样查询它.示例:`PersonModel.find({favouriteFoods.text:"sushi"},...); person = {name:String,favouriteFoods:[{text:String}]}` (9认同)
  • @AeroWang 使用这个 `db.person.find( { favouriteFoods: { $all: ["sushi", "sashimi"] } } )` 将返回所有喜欢“寿司”和“生鱼片”的人有人指出了一些答案以下 (4认同)
  • 当我想找到一个包含至少两个字符串的数组时会发生什么? (2认同)

Ali*_*son 137

$containsmongodb中没有操作员.

您可以使用JohnnyHK的答案.与mongo最接近的类比是$in,使用此查询看起来像:

PersonModel.find({ favouriteFoods: { "$in" : ["sushi"]} }, ...);
Run Code Online (Sandbox Code Playgroud)

  • 咦?这是不必要的.如果您有多个查询值并且文档需要匹配其中一个,则使用`$ in`.反过来(这就是这个问题的内容),JohnnyHK的回答是正确的.我本来打算投票,但我想这个答案可能对其他最终在这个页面上的人有所帮助. (35认同)
  • 使用单个值的$ in是没有意义的. (11认同)
  • 它是否正确?使用$ in时mongodb是不是期望一组值?比如{name:{$ in:["Paul","Dave","Larry","Adam"]}}? (10认同)
  • 谢谢.这就是我实际需要的,搜索多个值的方法:`PersonModel.find({favouriteFoods:{"$ in":["sushi","hotdog"]}}) (9认同)
  • 但这有助于我实际查询几个值:D非常感谢! (4认同)
  • @MalcolmOcean 是正确的,因为 $in 运算符是相反的,有一个数组作为*值*。*field* 是一个数组,这就是问题所在。但是,如果字段和值都是数组,那么这个答案和 JohnnyHK 的答案都是相关的,这意味着您确实需要 $in。 (2认同)

Pob*_*obe 83

$all在这种情况下,我觉得更合适.如果您正在寻找寿司的人,您可以:

PersonModel.find({ favoriteFood : { $all : ["sushi"] }, ...})
Run Code Online (Sandbox Code Playgroud)

您可能希望过滤更多搜索,例如:

PersonModel.find({ favoriteFood : { $all : ["sushi", "bananas"] }, ...})
Run Code Online (Sandbox Code Playgroud)

$in就像OR和$allAND一样.检查一下:https://docs.mongodb.com/manual/reference/operator/query/all/

  • 这是对您的问题的完美有效的答案!对于一个值,使用$ all或$ in没有区别.如果你有几个价值,如"寿司","香蕉",$ all正在寻找在他们最喜欢的食物阵列中有"寿司"和"香蕉"的人,如果使用$ in你得到的人有"寿司"或"香蕉" "在他们最喜欢的食物阵列中. (16认同)
  • 最好的答案。 (2认同)

Kfi*_*rez 50

如果数组包含对象,例如if favouriteFoods是以下对象的数组:

{
  name: 'Sushi',
  type: 'Japanese'
}
Run Code Online (Sandbox Code Playgroud)

您可以使用以下查询:

PersonModel.find({"favouriteFoods.name": "Sushi"});
Run Code Online (Sandbox Code Playgroud)

  • 这应该是选定的答案。如果您要查询 MongoDB 中的嵌套文档数组,您可以这样做。不确定它是否是最有效的,但如果这就是您想要做的,那么这就是您所需要的。 (4认同)
  • 这很容易成为最佳答案。当您赶时间时,使用起来要容易得多。 (3认同)

小智 32

如果你需要在子文档数组中找到包含NULL元素的文档,我发现这个查询非常有效:

db.collection.find({"keyWithArray":{$elemMatch:{"$in":[null], "$exists":true}}})
Run Code Online (Sandbox Code Playgroud)

此查询取自此帖子:具有空值的MongoDb查询数组

这是一个伟大的发现,它比我自己的初始和错误的版本(原来只适用于具有一个元素的数组)工作得更好:

.find({
    'MyArrayOfSubDocuments': { $not: { $size: 0 } },
    'MyArrayOfSubDocuments._id': { $exists: false }
})
Run Code Online (Sandbox Code Playgroud)


gau*_*tam 9

lookup_food_array 是数组。

match_stage["favoriteFoods"] = {'$elemMatch': {'$in': lookup_food_array}}
Run Code Online (Sandbox Code Playgroud)

lookup_food_array 的情况是字符串。

match_stage["favoriteFoods"] = {'$elemMatch': lookup_food_string}
Run Code Online (Sandbox Code Playgroud)


Rus*_*aev 8

有一些方法可以实现这一目标。第一个是按$elemMatch操作员:

const docs = await Documents.find({category: { $elemMatch: {$eq: 'yourCategory'} }});
// you may need to convert 'yourCategory' to ObjectId
Run Code Online (Sandbox Code Playgroud)

第二个是 by$in$all运算符:

const docs = await Documents.find({category: { $in: [yourCategory] }});
Run Code Online (Sandbox Code Playgroud)

或者

const docs = await Documents.find({category: { $all: [yourCategory] }});
// you can give more categories with these two approaches 
//and again you may need to convert yourCategory to ObjectId
Run Code Online (Sandbox Code Playgroud)

$in类似于 OR 和$allAND。有关更多详细信息,请检查此链接:https://docs.mongodb.com/manual/reference/operator/query/all/

第三个是按aggregate()功能:

const docs = await Documents.aggregate([
    { $unwind: '$category' },
    { $match: { 'category': mongoose.Types.ObjectId(yourCategory) } }
]};
Run Code Online (Sandbox Code Playgroud)

使用aggregate(),您只能在类别数组中获得一个类别ID。

我从我的项目中获取了此代码片段,在这些项目中我必须找到具有特定类别的文档,因此您可以根据您的需求轻松自定义它。