MongoDB查询:将文档投影为嵌套对象

4

您好,下面我已经指定了需要使用的数据并提供了输出结果,请问您可以帮我解决这个问题吗?我已经尝试了很多方法但是都没有找到解决方案。

//This is the data
let data = [
  {'name': 'A', 'parent': null},
  {'name': 'B', 'parent': null},
  {'name': 'C', 'parent': 'A'},
  {'name': 'D', 'parent': 'A'},
  {'name': 'E', 'parent': 'D'},
  {'name': 'F', 'parent': 'D'},
  {'name': 'G', 'parent': 'B'},
  {'name': 'H', 'parent': 'B'},
 ];

//And want the output like this by using mongodb aggregation
{
 "null": [
  {
   "A": [
    {
     "C": []
    },
    {
     "D": [
      {
       "E": []
      },
      {
       "F": []
      }
     ]
    }
   ]
  },
  {
   "B": [
    {
     "G": []
    },
    {
     "H": []
    }
   ]
  }
 ]
}

我尝试使用图形查找聚合,但无法摆脱它。

谢谢您的帮助!


深度是否可以超过3,还是像示例输出中显示的那样固定为3? - Dheemanth Bhat
@DheemanthBhat 应该按照输出所示进行修复。 - Creator Mind
@ CreatorMind 请检查更新后的答案。我会在下一次编辑中进行改进。您能确认第一稿是否可以吗? - Dheemanth Bhat
2个回答

1

在Mongoplayground中的解决方案

尝试一下:

db.collection.aggregate([
    {
        $lookup: {
            from: "collection",
            let: { name: "$name" },
            pipeline: [
                {
                    $match: {
                        $expr: { $eq: ["$parent", "$$name"] }
                    }
                },
                {
                    $lookup: {
                        from: "collection",
                        let: { name: "$name" },
                        pipeline: [
                            {
                                $match: {
                                    $expr: { $eq: ["$parent", "$$name"] }
                                }
                            },
                            {
                                $replaceRoot: {
                                    newRoot: {
                                        $arrayToObject: [[{ k: "$name", v: [] }]]
                                    }
                                }
                            }
                        ],
                        as: "children"
                    }
                },
                {
                    $replaceRoot: {
                        newRoot: {
                            $arrayToObject: [[{ k: "$name", v: "$children" }]]
                        }
                    }
                }
            ],
            as: "children"
        }
    },
    {
        $match: {
            children: { $ne: [] },
            parent: null
        }
    },
    {
        $group: {
            _id: "$parent",
            array: {
                $push: {
                    array: [{ k: "$name", v: "$children" }]
                }
            }
        }
    },
    {
        $addFields: {
            array: {
                $map: {
                    input: "$array",
                    as: "item",
                    in: { $arrayToObject: "$$item.array" }
                }
            }
        }
    },
    {
        $replaceRoot: {
            newRoot: { $arrayToObject: [[{ k: "null", v: "$array" }]] }
        }
    }
]);

输出:

{
    "null" : [
        {
            "A" : [
                {
                    "C" : [ ]
                },
                {
                    "D" : [
                        {
                            "E" : [ ]
                        },
                        {
                            "F" : [ ]
                        }
                    ]
                }
            ]
        },
        {
            "B" : [
                {
                    "G" : [ ]
                },
                {
                    "H" : [ ]
                }
            ]
        }
    ]
}

1
非常感谢!虽然这个阶段有点长,但没关系,它会帮助我进一步缩短流程。 - Creator Mind

0

你可以这样做。

  db.collection.aggregate([
  {
    $graphLookup: {
      from: "collection",
      startWith: "$name",
      connectFromField: "name",
      connectToField: "parent",
      as: "graph"
    }
  },
  {
    "$project": {
      name: 1,
      parent: 1
    }
  },
])

如果您想以数组形式显示它,可以创建对象并使用 $objectToArray 进行引用检查,请参阅链接。 $objectToArray


嗨!谢谢你的回复,但输出结果并不与我所提到的相同,尽管我没有考虑数组形式,但树形结构应该如图所示。 - Creator Mind

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