Remove all Node Descendants when remove Node parent in MongoDB

I have data in MongoDB as Tree Structures model.
Here is my data:

use TreeMongoParent;
db.categoriesPCO.insert({_id:"Electronics",parent:null});
db.categoriesPCO.insert({_id:"Cameras_and_Photography",parent:"Electronics", order:10});
db.categoriesPCO.insert({_id:"Digital_Cameras",parent:"Cameras_and_Photography", order:10});
db.categoriesPCO.insert({_id:"Camcorders",parent:"Cameras_and_Photography", order:20});
db.categoriesPCO.insert({_id:"Lenses_and_Filters",parent:"Cameras_and_Photography", order:30});
db.categoriesPCO.insert({_id:"Tripods_and_supports",parent:"Cameras_and_Photography", order:40});
db.categoriesPCO.insert({_id:"Lighting_and_studio",parent:"Cameras_and_Photography", order:50});
db.categoriesPCO.insert({_id:"Shop_Top_Products",parent:"Electronics", order:20});
db.categoriesPCO.insert({_id:"IPad",parent:"Shop_Top_Products", order:10});
db.categoriesPCO.insert({_id:"IPhone",parent:"Shop_Top_Products", order:20});
db.categoriesPCO.insert({_id:"IPod",parent:"Shop_Top_Products", order:30});
db.categoriesPCO.insert({_id:"Blackberry",parent:"Shop_Top_Products", order:40});
db.categoriesPCO.insert({_id:"Cell_Phones_and_Accessories",parent:"Electronics", order:30});
db.categoriesPCO.insert({_id:"Cell_Phones_and_Smartphones",parent:"Cell_Phones_and_Accessories", order:10});
db.categoriesPCO.insert({_id:"Headsets",parent:"Cell_Phones_and_Accessories", order:20});
db.categoriesPCO.insert({_id:"Batteries",parent:"Cell_Phones_and_Accessories", order:30});
db.categoriesPCO.insert({_id:"Cables_And_Adapters",parent:"Cell_Phones_and_Accessories", order:40});
db.categoriesPCO.insert({_id:"Nokia",parent:"Cell_Phones_and_Smartphones", order:10});
db.categoriesPCO.insert({_id:"Samsung",parent:"Cell_Phones_and_Smartphones", order:20});
db.categoriesPCO.insert({_id:"Apple",parent:"Cell_Phones_and_Smartphones", order:30});
db.categoriesPCO.insert({_id:"HTC",parent:"Cell_Phones_and_Smartphones", order:40});
db.categoriesPCO.insert({_id:"Vyacheslav",parent:"Cell_Phones_and_Smartphones", order:50});

In my practices, I want to remove Node parent means delete all Node Descendants.

For example:

When I remove " Cell_Phones_and_Accessories " node, it must remove Cell_Phones_and_Smartphones , Headset , Battery , Cables_And_Adapter , Nokia , Samsung , HTC , Apple and Vyacheslav

I have mongo shell to get all Node Descendants. Here is my code:

var stack=[];
var item = db.categoriesPCO.findOne({_id:"Cell_Phones_and_Accessories"});
stack.push(item);
while (stack.length>0){
   var currentnode = stack.pop();
   var children = db.categoriesPCO.find({parent:currentnode._id});
   while(true === children.hasNext()) {
       var child = children.next();
       descendants.push(child._id);
       stack.push(child);
    }
}
descendants.join(",")

Here is output

Cell_Phones_and_Smartphones,Headsets,Batteries,Cables_And_Adapters,Nokia,Samsung,Apple,HTC,Vyacheslav
1 Like

Hello @Napoleon_Ponaparte :wave: , somehow the name sounds quite familiar!

You can use this aggregate query to get the node and all its descendant nodes - and then delete all of them.

TOP_LEVEL_PARENT = "Cell_Phones_and_Accessories"

db.categoriesPCO.aggregate( [
   {
      $graphLookup: {
          from: "categoriesPCO",
          startWith: "$parent",
          connectFromField: "parent",
          connectToField: "_id",
          as: "hierarchy"
      }
   },
  { 
      $match: { 
          $or: [ 
             { "hierarchy._id":  TOP_LEVEL_PARENT },
             { _id: TOP_LEVEL_PARENT }
          ]
      } 
  }
] 
).forEach( doc => db.categoriesPCO.deleteOne( { _id: doc._id } ) )
4 Likes

Thank you Sir.
It worked for me.