Mongo查询子文档的多个字段

Gre*_*reg 14 mongodb mongodb-query

假设我有一个这样的集合:

{ "arr" : [ { "name" : "a", "num" : 1 }, { "name" : "a", "num" : 2 } ] },
{ "arr" : [ { "name" : "b", "num" : 1 }, { "name" : "a", "num" : 2 } ] },
{ "arr" : [ { "name" : "b", "num" : 1 }, { "name" : "b", "num" : 2 } ] }
Run Code Online (Sandbox Code Playgroud)

我想找到所有arr包含a name="b"和num= 2 的子文档的文档.

如果我这样做一个查询:

db.collection.find({
    $and: [
        { "arr.name": "b" },
        { "arr.num": 2 }
    ]
});
Run Code Online (Sandbox Code Playgroud)

它将返回集合中的所有文档,因为它们每个都包含一个带有name"b"或a num为2 的子文档.

我也试过这个:

db.collection.find({
    arr: [
        { "name": "b", "num": 2 }
    ]
});
Run Code Online (Sandbox Code Playgroud)

它不会抛出任何错误,但不会返回任何结果.

你如何查询MongoDB中的多个子文档字段?

Nei*_*unn 32

这实际上是$elemMatch操作员的用途,即使它经常被滥用.它基本上对数组中"内"的每个元素执行查询条件.除非另外明确调用,否则所有MongoDB参数都是"和"操作:

db.collection.find({ "arr": { "$elemMatch": { "name": "b", "num": 2  } } })
Run Code Online (Sandbox Code Playgroud)

如果您只期望匹配的字段而不是整个文档,那么您可能也希望在此处"投影":

db.collection.find(
    { "arr": { "$elemMatch": { "name": "b", "num": 2  } } },
    { "arr.$": 1 }
)
Run Code Online (Sandbox Code Playgroud)

最后解释为什么你的第二次尝试不起作用,这个查询:

db.collection.find({
    "arr": [
        { "name": "b", "num": 2 }
    ]
})
Run Code Online (Sandbox Code Playgroud)

不匹配任何东西,因为没有实际文档,其中"arr"包含与您的条件完全匹配的单数元素.

你的第一个例子失败了..:

db.collection.find({
    $and: [
        { "arr.name": "b" },
        { "arr.num": 2 }
    ]
});
Run Code Online (Sandbox Code Playgroud)

因为有几个数组元素满足条件,这不仅仅考虑两个条件都适用于同一个元素.这就是$elemMatch添加,当你需要更多的那个条件来匹配时,这就是你使用它的地方.