首页 > 解决方案 > 查询 MongoDB 中嵌套文档中的所有嵌套文档

问题描述

我有一个包含如下文档的集合:

{ keyA1: "stringVal",
  keyA2: "stringVal",
  keyA3: { keyB1: { feild1: intVal,
                    feild2: intVal}
           keyB2: { feild1: intVal,
                    feild2: intVal}
          }
 }

目前 [keyB1, keyB2, ...] 集合是 7 个键,对于集合中的所有文档都是相同的。我想查询allintVals的on 特定fields的。因此,例如,我可能希望找到所有价值大于 100的文档,无论它属于哪个文档。 keyBfield2keyB

对于任何一个特定keyB的 ,我只使用点符号:{"keyA3.keyB2.field2": {$gte: 100}}. 现在,我可以选择循环遍历所有keyB's,但将来可能不会出现这种情况,因为将来keyB可以添加更多值。那时我不想修改代码,并且无论如何都希望避免对这些值进行编码。我还需要相当快的解决方案,因为最终部署预计会有超过 20M 的文档。

如何编写一个可以“跳过”keyB点符号中的字段并只浏览所有嵌入式文档的查询?

FWIW,我正在使用 pymongo 在 python 中实现它。谢谢。

标签: mongodbpymongo

解决方案


首先将keyA3对象转换为数组并添加新字段,$addFields 然后filter新数组匹配 field2 值大于 100 然后查询匹配数组大小大于 0 的文档,然后删除我们添加的额外字段

db.collection.aggregate([
  {
    "$addFields": {
      "arr": {
        "$objectToArray": "$keyA3"
      }
    }
  },
  {
    "$addFields": {
      "matchArrSize": {
        $size: {
          "$filter": {
            "input": "$arr",
            "as": "z",
            "cond": {
              $gt: [
                "$$z.v.feild2",
                100
              ]
            }
          }
        }
      }
    }
  },
  {
    $match: {
      matchArrSize: {
        $gt: 0
      }
    }
  },
  {
    $unset: [
      "arr",
      "matchArrSize"
    ]
  }
])

https://mongoplayground.net/p/VumwL9y7Km1


推荐阅读