I am building an application to show tree structures via jstree. The data is stored in flat array format like the following.
{id:1,text:"Parent",xpath:"/Parent",parent:"#",children:true}
{id:2,text:"Child1",xpath:"/Parent/Child1",parent:1,children:false}
{id:3,text:"Child2",xpath:"/Parent/Child2",parent:1,children:true}
{id:4,text:"Child3",xpath:"/Parent/Child3",parent:1,children:false}
{id:5,text:"Grandchild1",xpath:"/Parent/Child2/Grandchild1",parent:3,children:false}
{id:6,text:"Grandchild2",xpath:"/Parent/Child2/Grandchild2",parent:3,children:false}
{id:7,text:"Grandchild3",xpath:"/Parent/Child2/Grandchild3",parent:3,children:false}
Every document contains a node and has the following attributes
id -> Uniquer identifier
text -> node name
xpath -> path from root to node
parent -> node id of node's parent
children -> Boolean value representing whether the node has children
Once I provide a particular node id. I want all the descendants of the node. For example, if I provide node id as 1, I need results in the following pattern.
{
1:[{id:2,...},{id:3,...},{id:4,...}],
3:[{id:5,...},{id:6,...},{id:7,...}]
}
Is there any way to achieve this? Should I change the format in which data is stored to achieve this? Open to any suggestion. Thanks!
CodePudding user response:
I'm not sure how flexible you are with the output format, but here's one way to output all the descending generations of a given "id"
.
db.collection.aggregate([
{"$match": {"id": 1}},
{
"$graphLookup": {
"from": "collection",
"startWith": "$id",
"connectFromField": "id",
"connectToField": "parent",
"as": "descendents",
"depthField": "generation"
}
},
{"$unwind": "$descendents"},
{"$sort": {"descendents.id": 1}},
{
"$group": {
"_id": "$descendents.generation",
"theChildren": {"$push": "$descendents"}
}
},
{
"$project": {
"_id": 0,
"theChildren": 1,
"generation": {"$toInt": "$_id"},
"parent": {"$first": "$theChildren.parent"}
}
}
])
Try it on mongoplayground.net.