Home > OS >  MongoDB addfields based on filter condition
MongoDB addfields based on filter condition

Time:08-09

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:

  1. Create an array of items that are children of the wanted node (called data)
  2. Create a set of nodes in data which have children (called childrenExists)
  3. Unwind data as you want the answer as separate documents.
  4. 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

  • Related