在 MongoDB 中使用平面文档创建粒度

Create granularity with flat docs in MongoDB

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

我在 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"
            ]
        }
    }
}

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

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

如果可能的话,您是否有使用管道操作员的想法?

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

  • $gorup按前3个级别,组成第三级字段数组
  • $group 前2层,使第二层数组为k(key)和v(value)格式
  • $group 通过第二个 1 顶层并创建第一层数组并使用 $objectToArray
  • 将第二层从数组转换为对象
  • 使用 $arrayToObject 将第二级从数组转换为对象,并使用 $arrayToObject
  • 创建第一级数组并转换为对象
  • $replaceRoot 将一级对象替换为 root
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" } }
        ]]
      }
    }
  }
])

Playground