mongodb - 通过投影从嵌套文档中删除除一个字段之外的所有字段

标签 mongodb mongodb-query projection aggregation-framework

这是我的示例文档:

{
  a: 42,
  map: {
    x: { ... },
    y: { ... },
    z: { ... }
  }
}

我正在寻找一种仅返回的方法:

{
  a: 42,
  map: {
    y: { ... }
  }
}

我只想指定 map 内要保留的字段。类似这样的事情...

db.myCollection.find({},
  {
    "map.y":1
  }
)

...但是它也应该返回字段a而不明确指定它。

我知道我还可以删除不需要的 map 条目:

db.myCollection.find({},
  {
    "map.x":0,
    "map.z":0
  }
)

但是这样,我需要在运行查询之前知道哪些 map 键可用。

有没有好的方法来处理这个问题?也许使用聚合框架?

谢谢:)

最佳答案

这基本上就是 MongoDB 以及许多其他数据库系统中投影或字段选择的工作原理。这里的概念基本上是“全有或全无”,因为如果您没有指定要返回的所有字段,则它们不会返回,当然默认情况下会返回您没有具体说明想要的内容的所有内容.

因此,当前数据仅返回 amap.y 的正确形式是:

db.myCollection.find({}, { "a": 1, "map.y": 1 })

或者当然你可以告诉它你不想要什么:

db.myCollection.find({}, { "map.x": 0, "map.z": 0 })

但是您不能“混合”包含和排除,唯一的异常(exception)是 _id 字段,您不希望在结果中出现该字段,可能会想到“覆盖索引”查询,但通常您想要主键:

db.myCollection.find({}, { "_id": 0, "a": 1, "map.y": 1 })

对于聚合框架来说,它是一样的,并且对于像$project这样的运算符来说尤其同样残酷。和 $group 。在这两种情况下,您都需要准确指定要返回的内容( $project 也遵循一般投影规则),否则这些字段不会出现在结果中。

事实上,我的人员犯的一个常见错误是使用这些阶段之一“删除”字段,然后尝试引用稍后删除的字段。它是一个“管道”,就像 Unix 管道 | 一样,流向下一阶段的唯一内容是您指定的内容:

唯一“真实”的情况是,您可以排除除匹配字段之外的所有字段而不指定其他字段,方法是更改​​结构以将“map”实现为数组,然后使用 $redact管道阶段,从 MongoDB 2.6 及更高版本可用。虽然有点做作:

db.test.insert({
    "a": 42,
    "map": [
        { "type": "x", "content": {} },
        { "type": "y", "content": {} },
        { "type": "z", "content": {} }
    ]
})

以及对这样的数据结构的聚合操作:

db.test.aggregate([
    { "$redact": {
        "$cond": [
            { "$eq": [
                { "$ifNull": [ "$type", "y" ] },
                "y"
            ]},
            "$$DESCEND",
            "$$PRUNE"
        ]
    }}
])

所以我们只要求匹配“type”等于“y”的元素,但这里通常需要小心,因为 $redact 是递归处理的,这就是 $ifNull 的原因。运算符在测试字段不存在的级别人为地创建匹配。

但一般来说,投影要么全有,要么全无。指定您要返回的字段,否则它们将不存在。

关于mongodb - 通过投影从嵌套文档中删除除一个字段之外的所有字段,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25696731/

相关文章:

opencv - OpenCv StereoRectify 中矩阵的精确定义

javascript - TypeError : C:\nodetest1\views\userlist. Jade :7

javascript - 聚合以按大小创建文档组

javascript - nodejs mongodb不根据id删除

node.js - Mongo 查询没有给出聚合函数的准确结果

mongodb - 在双重嵌套数组 MongoDB 中查找

spring - 如何在 Spring Data REST 项目中使用 DTO?

openlayers - 如何将 OpenLayers 3 与 Proj4js 一起使用

javascript - 从 mongodb 中的对象更新字符串

MongoDB mongoexport 查询