【问题标题】:Query on all nested docs inside a nested doc in MongoDB查询 MongoDB 中嵌套文档中的所有嵌套文档
【发布时间】:2021-11-12 00:48:00
【问题描述】:

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

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

目前 [keyB1, keyB2, ...] 集合是 7 个键,对于集合中的所有文档都是相同的。我想查询特定fields 上的intVals 以获取all keyB's。因此,例如,我可能希望找到所有 field2 的值大于 100 的文档,其中 keyB 属于。

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

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

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

【问题讨论】:

    标签: mongodb pymongo


    【解决方案1】:

    首先将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

    【讨论】:

    • 感谢您的回复!我可以看到,如果我也想将结果限制为 keyB 值的子集(我可以使用 $$z.k),这种方法也可以工作,这很棒。我的一个问题是,如果我要重组文档以将数组作为 keyA3 值,查询会更快吗?这样就可以使用 find() 而不是 aggregate() 来完成这些操作。
    • 我认为是的,如果你重组你的数据我认为更快,但我认为重组你的数据并发送查询以检测查询速度
    猜你喜欢
    • 2018-03-09
    • 2021-02-25
    • 2016-08-16
    • 2023-03-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多