首页 > 解决方案 > 在 MongoDB 中使用平面文档创建粒度

问题描述

首先,我不知道我的存储方法是否合适,但我尝试过这样。我想从动态数据创建一个表单(在前面)并从论文中创建一个选择表单。

我在 mongo 中有一个集合,其中每个字段都引用一个枚举。

{
    {
        _id: "xxx",
        "Parent":"ParentEnum1",
        "firstChild": "firstChildEnum2",
        "secondChild": "secondChildEnum3",
        "thirdChild":"thirdChildEnum1",
    },
    {
        _id: "xxx",
        "Parent":"ParentEnum1",
        "firstChild": "firstChildEnum1",
        "secondChild": "secondChildEnum3",
        "thirdChild":"thirdChildEnum1",
    },
    {
        _id: "xxx",
        "Parent":"ParentEnum2",
        "firstChild": "firstChildEnum2",
        "secondChild": "secondChildEnum5",
        "thirdChild":"thirdChildEnum8,
    },
    {
        _id: "xxx",
        "Parent":"ParentEnum2",
        "firstChild": "firstChildEnum2",
        "secondChild": "secondChildEnum1",
        "thirdChild": null,
    },
    {
        _id: "xxx",
        "Parent":"ParentEnum4",
        "firstChild": "firstChildEnum4",
        "secondChild": "secondChildEnum1",
        "thirdChild":"thirdChildEnum5,
    },
    {
        _id: "xxx",
        "Parent":"ParentEnum1",
        "firstChild": "firstChildEnum4",
        "secondChild": "secondChildEnum5",
        "thirdChild":"thirdChildEnum7,
    },
    {
       ...
    }
}

从该文档中,我想获得这样的层次结构:

{

    "ParentEnum1":{
        firstChildEnum4:{
            secondChildEnum5:[
                thirdChildEnum7,
            ]
        },
        firstChildEnum1:{
            secondChildEnum3:[
                thirdChildEnum1,
            ]
        },
        firstChildEnum2:{
            secondChildEnum3:[
                thirdChildEnum1,
            ]
        }
    },
    "ParentEnum2":{
        "firstChildEnum2":{
            "secondChildEnum5":[
                "thirdChildEnum8"
            ],
            "secondChildEnum1":[]
        }
    },
    "ParentEnum4":{
        "firstChildEnum4":{
            "secondChildEnum5":[
                "thirdChildEnum7"
            ]
        }
    }
}

为此,我尝试使用聚合组,但我只能使用 a$group和 a字段获得第$addToSet一个粒度。firstChild我认为我可以做得更好,$bucket但我尝试过但没有成功(也许我没有正确使用它)

我不知道我想做的事情是否可行,那么我愿意接受任何其他建议。

如果可能,您是否有使用管道运营商的想法?

标签: mongodbaggregation

解决方案


可能会有一些更有效的方法,但根据您的要求,这是 4 个级别的限制,

  • $gorup按前 3 级并制作第三级字段的数组
  • $group按前 2 级,将第二级数组设为 k(key) 和 v(value) 格式
  • $group通过第二个顶层并制作第一级数组并使用将第二级从数组转换为对象$objectToArray
  • 使用将第二级从数组转换为对象$arrayToObject,并使用创建第一级数组并转换为对象$arrayToObject
  • $replaceRoot将第一级对象替换为根
db.collection.aggregate([
  {
    $group: {
      _id: {
        Parent: "$Parent",
        firstChild: "$firstChild",
        secondChild: "$secondChild"
      },
      thirdChild: { $push: "$thirdChild" }
    }
  },
  {
    $group: {
      _id: {
        Parent: "$_id.Parent",
        firstChild: "$_id.firstChild"
      },
      secondChild: {
        $push: { k: "$_id.secondChild", v: "$thirdChild" }
      }
    }
  },
  {
    $group: {
      _id: "$_id.Parent",
      firstChild: {
        $push: { k: "$_id.firstChild", v: { $arrayToObject: "$secondChild" } }
      }
    }
  },
  {
    $replaceRoot: {
      newRoot: {
        $arrayToObject: [[
          { k: "$_id", v: { $arrayToObject: "$firstChild" } }
        ]]
      }
    }
  }
])

操场


推荐阅读