I have data for jstree in the flat array format
{
"glob":[
{
id:"1",
text:"Parent",
parent:"#"
},
{
id:"2",
text:"child1",
parent:"1"
},
{
id:"3",
text:"child2",
parent:"1"
},
{
id:"4",
text:"grandchild1",
parent:"3"
},
]
}
I want to retrieve the children of a particular node id along with an attribute to explain whether the node has children.
So, if I retrieve the children for node id '1', the expected result is
[
{
id:"2",
text:"child1",
parent:"1",
children: false
},
{
id:"3",
text:"child2",
parent:"1",
children: true
}
]
Can you please suggest the right stages I have to use
CodePudding user response:
Since the documents are originally nested we cant use $graphLookup
or $lookup
which are built for such cases. One option is to:
- Create an array of items that are children of the wanted node (called
data
) - Create a set of nodes in data which have children (called
childrenExists
) - Unwind
data
as you want the answer as separate documents. - format the answer.
db.collection.aggregate([
{$set: {
data: {
$filter: {input: "$glob", cond: {$eq: ["$$this.parent", "1"]}}
}
}
},
{$project: {
_id: 0,
data: 1,
childrenExists: {
$reduce: {
input: "$glob",
initialValue: [],
in: {$setUnion: [
"$$value",
{$cond: [
{$in: ["$$this.parent", "$data.id"]},
["$$this.parent"],
[]
]}
]}
}
}
}
},
{$unwind: "$data"},
{$set: {
"data.children": {
$cond: [{$in: ["$data.id", "$childrenExists"]}, true, false]
},
childrenExists: "$$REMOVE"
}
},
{$replaceRoot: {newRoot: "$data"}}
])
See how it works on the playground example