如何在MongoDB的同一集合中查找文档

3
我在MongoDB中有以下文档[更新:缩短了文档]。
{
  "sections": [
    {
      "_id": {
        "$oid": "64cbeb62b669cd29a5719a8f"
      },
      "categories": [
        {
          "measureValues": [
            "64cbeb62b669cd29a5719a95",
            "64cbeb62b669cd29a5719a99"
          ]
        }
      ]
    }
  ],
  "measures": [
    {
      "_id": {
        "$oid": "64cbeb62b669cd29a5719a93"
      },
      "name": {
        "64cbeb62b669cd29a5719a92": {
          "nodeType": "nodeName",
          "value": "measure-1"
        }
      },
      "measureValues": [
        {
          "_id": {
            "$oid": "64cbeb62b669cd29a5719a95"
          },
          "measureValues": {
            "nodeName": {
              "64cbeb62b669cd29a5719a94": {
                "nodeType": "nodeName",
                "value": "measureValue",
                "_class": "com.myapp.cqrsdemo.model.DataObj"
              }
            },
            "comment": {
              "64cbeb62b669cd29a5719a97": {
                "nodeType": "comment",
                "value": "this is a comment",
                "_class": "com.myapp.cqrsdemo.model.DataObj"
              }
            }
          },
          "categoriesIds": [
            "64cbeb62b669cd29a5719a91"
          ],
          "measureName": "measure-1"
        },
        {
          "_id": {
            "$oid": "64cbeb62b669cd29a5719a99"
          },
          "measureValues": {
            "nodeName": {
              "64cbeb62b669cd29a5719a98": {
                "nodeType": "nodeName",
                "value": "measureValue",
                "_class": "com.myapp.cqrsdemo.model.DataObj"
              }
            },
            "date": {
              "64cbeb62b669cd29a5719a9b": {
                "nodeType": "date",
                "value": "2023-02-02",
                "_class": "com.myapp.cqrsdemo.model.DataObj"
              }
            }
          },
          "categoriesIds": [
            "64cbeb62b669cd29a5719a91"
          ],
          "measureName": "measure-1"
        }
      ]
    }
  ],
  "_class": "com.myapp.cqrsdemo.model.ProjectGroup"
}

我想提取“measures”下的“measureValues”,其中“measureValues”的id与categories下的measureValues的id匹配。我希望在categories下包含measureValue对象,而不仅仅是Ids。
我该如何做到这一点?我尝试编写聚合管道,但失败了。
我的输出应该如下所示。
{
  "sections": [
    {
      "_id": {
        "$oid": "64cbeb62b669cd29a5719a8f"
      },
      "categories": [
        {
          "measureValues": [
            {
              "_id": {
                "$oid": "64cbeb62b669cd29a5719a95"
              },
              "measureValues": {
                "nodeName": {
                  "64cbeb62b669cd29a5719a94": {
                    "nodeType": "nodeName",
                    "value": "measureValue",
                    "_class": "com.myapp.cqrsdemo.model.DataObj"
                  }
                },
                "comment": {
                  "64cbeb62b669cd29a5719a97": {
                    "nodeType": "comment",
                    "value": "this is a comment",
                    "_class": "com.myapp.cqrsdemo.model.DataObj"
                  }
                }
              },
              "categoriesIds": [
                "64cbeb62b669cd29a5719a91"
              ],
              "measureName": "measure-1"
            },
            {
              "_id": {
                "$oid": "64cbeb62b669cd29a5719a99"
              },
              "measureValues": {
                "nodeName": {
                  "64cbeb62b669cd29a5719a98": {
                    "nodeType": "nodeName",
                    "value": "measureValue",
                    "_class": "com.myapp.cqrsdemo.model.DataObj"
                  }
                },
                "date": {
                  "64cbeb62b669cd29a5719a9b": {
                    "nodeType": "date",
                    "value": "2023-02-02",
                    "_class": "com.myapp.cqrsdemo.model.DataObj"
                  }
                }
              },
              "categoriesIds": [
                "64cbeb62b669cd29a5719a91"
              ],
              "measureName": "measure-1"
            }
          ]
        }
      ]
    }
  ],
  "_class": "com.myapp.cqrsdemo.model.ProjectGroup"
}

1
你能展示一下你想要的结果和你尝试过的聚合管道吗? - rickhg12hs
1
你能简化一下问题吗?看起来你发布了一个很大的示例文档,其中许多字段在你的问题中并不起作用。这些额外的数据点使得别人帮助你变得更加困难。#帮我帮你 - barrypicker
@barrypicker - 我已经更新了输入文档的缩短版本,并且上传了所需的输出文件。 - Pushpak
还是一个相当大的文件。你尝试了哪个流程?你所说的“失败”是什么意思? - Wernfried Domscheit
使用动态键名(例如64cbeb62b669cd29a5719a9b)通常是一个糟糕的设计,它会让你的生活变得更加困难。而且看起来你混合了ObjectId$oid)和字符串值,这也不是很明智的做法。 - Wernfried Domscheit
根据给定的数据,简单地使用db.collection.aggregate([{ $project: { _class: 1, sections: { categories: { $first: "$measures.measureValues" } } } }])即可。但是你缺少一些信息:哪个数组可以为空?数组元素是否总是唯一的?还不清楚哪些元素被定义为数组,尽管它们始终只有一个元素(因此最好不要将其存储为数组)。 - Wernfried Domscheit
1个回答

1

一个选项是:

  1. 创建一个变量measureValuesArr,并将其存储为包含所有measures下的所有measureValues的扁平化数组
  2. 由于sections.categories.measureValues是一个双重嵌套数组(在一个数组内部的数组),使用双层$map来获取其中的所有实例。
  3. 使用$arrayElemAt$indexOfArray来找到measureValuesArr中匹配的measureValues项。
db.collection.aggregate([
  {$set: {
      sections: {$let: {
          vars: {measureValuesArr: {$reduce: {
                input: "$measures",
                initialValue: [],
                in: {$concatArrays: ["$$value", "$$this.measureValues"]}
          }}},
          in: {$map: {
              input: "$sections",
              as: "s",
              in: {$mergeObjects: [
                  "$$s",
                  {categories: {$map: {
                        input: "$$s.categories",
                        as: "c",
                        in: {$mergeObjects: [
                            "$$c",
                            {measureValues: {$map: {
                                  input: "$$c.measureValues",
                                  as: "m",
                                  in: {$arrayElemAt: [
                                      "$$measureValuesArr",
                                      {$indexOfArray: [
                                          "$$measureValuesArr._id",
                                          {$toObjectId: "$$m"}
                                      ]}
                                  ]}
                            }}}
                        ]}
                  }}}
              ]}
          }}
      }}
  }}
])

看看在示例操场上是如何工作的

*这个解决方案假设如果在measures下不存在匹配的对象,那么查询应该添加对这种情况的处理。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接