marcus
marcus

Reputation: 47

When child document is deleted, how to delete its reference inside parent document in Mongoose?

In Mongoose, I have a parent document that has an array of child references.

Subject has many Topics:

Inside Subject.js:
const SubjectSchema = new Schema({   
  topics: [{
    type: Schema.Types.ObjectId,
    ref: 'topic'
  }]
...

When I delete a topic, I would like its reference removed from Subject.topics array.

Any help will be appreciated!

Upvotes: 2

Views: 1982

Answers (2)

Rakib Hasan
Rakib Hasan

Reputation: 21

Maybe something like this will work if you have an id :

Topics.findByIdAndRemove({ id }, (err) => {
    if(err)
        console.error(err);

    Subjects.update({ 
        "topics" : { $in : [id] } 
    }, { 
        $pullAll : { "topics" : [id] }
    } , (err, subject) => {

    })
})

Upvotes: 2

Saurabh Lende
Saurabh Lende

Reputation: 1003

I think you should use mongoose middleware for this. I have done exactly opposite to your question. If parent document is deleted then I want to delete its referenced child document also. I am posting my code here. Hope it will help you.

I have two model file

  1. RealEstateProperty

  2. RealEstateProject (Parent)

RealEstateProperty :

var RealEstatePropertySchema   = new Schema({
    Type : { type : String, enum : ['2BHK','3BHK','1BHK','3.5BHK','4BHK','5BHK','1RK','1.5BHK','2.5BHK','4.5BHK','5.5BHK','Penthouse','Plot'], required : true },
    Area : { type : String, required: true },
    Price : { type : Number, required: true },
    NumberOfUnits : { type : Number, required: true },
    Gallery : [{ type : String, required: false }],
    PricePerSquareFoot : { type : Number, required: true },
    CreateDate : { type : Date, required: false },
    UpdateDate : { type : Date, required: false, default: Date.now },
    Project : { type : mongoose.Schema.Types.ObjectId, ref:'RealEstateProject', required : true},
    Status : { type : String, enum : ['Under Construction', 'Ready to move'],required  : false }
});

RealEstateProject (Parent) :

var RealEstateProjectSchema   = new Schema({
    Name : { type : String, required: true },
    Description : { type : String, required: true },
    DetailAddress : { type : String, required: true },
    ShortAddress : { type : String, required: true },
    Area : { type : Number, required: true },
    City : { type : String, required: true },
    Pincode : { type : Number, required: true },
    CreateDate : { type : Date, required: false },
    UpdateDate : { type : Date, required: false, default : Date.now() },
    IsActive : { type : Boolean, required: false },
    Amenities: [{ type : String, required : true }],
    Possession: { type : String, required : true },
    ProjectType: { type : String, enum : ['Apartment', 'Land', 'Bungalow', 'Row House', 'Villas'], required : true },
});

//mongoose middleware to remove reference docs
RealEstateProjectSchema.pre('remove',function(next){
    console.log("Removing property of project " + this._id);
    //code to remove RealEstateProperties reference by RealEstateProject
    //Note : Here you can use $unset to clear the refernce
    this.model('RealEstateProperty').find({ Project : this._id }, function(err,properties){
        if(err){
            console.log("No property found in this project");
        }else if(properties.length == 0){
            console.log("No property found in this project");
        }else{
            for (var i=0; i<properties.length; i++){
                 properties[i].remove(function(delete_err,delete_data){
                    if(delete_err){
                        console.log("No property found in this project");
                    }else{
                        console.log("Properties deleted");
                    }
                });
            }
        }
    });
    next();
});

When RealEstateProject is removed

RealEstateProject.findOne({ id : req.body.id })
.exec(function(err,project){
   if(err){
       console.log(err);
       res.json(err);
   } else{
       if(!project){
           console.log("Project not found");
           res.json({error:"Project not found, invalid Project id"});
       }else{
           project.remove(function(delete_project_err,delete_project_data){
               if(delete_project_err){
                   console.log(delete_project_err);
                   res.json(delete_project_err);
               }else{
                   console.log("Project removed successfully");
                    res.json({result:1});
               }
           });
       }
   }
});

On 'remove', middleware is called and delete docs in RealEstateProperty with same reference id.

Upvotes: 0

Related Questions