4

Hello Below I have specify the data which is to be used and get an output which I have mentioned below, Can you please help me on that as I tried alot but couldn't find a way.

//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": []
    }
   ]
  }
 ]
}

I have tried using graphlookup aggregation but couldn't find a way out of it.

Thanks for your help !

3
  • Can the depth be more than 3 or is it fixed as shown in sample output? Commented Mar 31, 2021 at 5:59
  • @DheemanthBhat It should be fixed as shown in the output Commented Mar 31, 2021 at 12:32
  • @ CreatorMind Check the updated answer. I will improve it in next edit. Can you confirm if the first draft is ok? Commented Mar 31, 2021 at 17:02

2 Answers 2

1

Solution in Mongoplayground.

Try this:

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" }]] }
        }
    }
]);

Output:

{
    "null" : [
        {
            "A" : [
                {
                    "C" : [ ]
                },
                {
                    "D" : [
                        {
                            "E" : [ ]
                        },
                        {
                            "F" : [ ]
                        }
                    ]
                }
            ]
        },
        {
            "B" : [
                {
                    "G" : [ ]
                },
                {
                    "H" : [ ]
                }
            ]
        }
    ]
}
Sign up to request clarification or add additional context in comments.

1 Comment

Thanks alot ! As its bit lengthy stages but never mind it would help me for further process to cut it down.
0

You can do it this way.

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

If you want to show it in array form you can create object and can use $objectToArray for ref check the link. $objectToArray

1 Comment

Hey! Thanks for your response , but the output is not same as I have mentioned though I I am not considering the array forms but the tree structure should be there as shown.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.