假设我有一个这样的Collection :

{ "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 } ] }

我想找到所有arr岁的文档,其中包含一个name="b"和num=2的子文档.

如果我做这样的查询:

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

它将返回集合中的所有文档,因 for each 文档都包含一个子文档,该子文档的"b"值为name,或"2"值为num.

我也试过:

db.collection.find({
    arr: [
        { "name": "b", "num": 2 }
    ]
});

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

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

推荐答案

这实际上就是$elemMatch运算符的用途,尽管它经常被误用.它基本上对数组中的每个元素执行查询条件.除非另有明确调用,否则所有MongoDB参数都是"and"操作:

db.collection.find({ "arr": { "$elemMatch": { "name": "b", "num": 2  } } })

如果只需要匹配的字段,而不需要匹配的字段,那么您可能也希望在这里"投影"

db.collection.find(
    { "arr": { "$elemMatch": { "name": "b", "num": 2  } } },
    { "arr.$": 1 }
)

最后,要解释第二次try 失败的原因,请执行以下查询:

db.collection.find({
    "arr": [
        { "name": "b", "num": 2 }
    ]
})

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

您的第一个示例失败了

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

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

Mongodb相关问答推荐

基于另一子文档更改子文档的引用

MongoDB:如何通过增量向量递增整数向量

MongoDB/Mongoose查询:使用优先约束检索从位置A到位置B的路径

从MongoDB中的嵌套数组中提取找到的值及其索引

在服务器上部署后端时判断??=默认判断

如何在Mongo中查找数组中的特定对象

MongoDB聚合:如何将查找结果放入嵌套数组中?

在 Mongo 聚合中,可以通过分组生成 3 个不同的计数

MongoDB - 分组并找到前 N 个

如何聚合过滤器嵌套文档并从其他字段中获取值

Meteor 和 Fibers/bindEnvironment() 是怎么回事?

解析命令行时出错:unrecognized option --rest

无法提取地理键,经度/纬度超出范围

Node.js 和 MongoDB,重用 DB 对象

mongodb nodejs - 转换圆形 struct

用于嵌入式集合的 MongoDB 首选模式.文档与数组

没有数组的嵌入文档?

使用 Node.js 将许多记录插入 Mongodb 的正确方法

从 mongo 结果中删除 _id

MongoDB备份计划