Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Mongoose remove document with references

I have two Schemas, eventSchema and personSchema as shown below:

var mongoose = require('mongoose')
    , Schema = mongoose.Schema

var eventSchema = Schema({
    title     : String,
    location  : String,
    startDate : Date,
    endDate   : Date
});

var personSchema = Schema({
    firstname: String,
    lastname: String,
    email: String,
    dob: Date,
    city: String,
    eventsAttended: [{ type: Schema.Types.ObjectId, ref: 'Event' }]
});

var Event  = mongoose.model('Event', eventSchema);
var Person = mongoose.model('Person', personSchema);

How can I remove all eventsAttended from a deleted Person?

For example, if I remove a Person then I expect that all events assigned to that Person will be removed.

This is my code:

  Person.findOneAndRemove({_id: req.body._id}, (err, response) => {
    // remove the events assigned to this person
  })
like image 483
Valip Avatar asked Oct 24 '17 13:10

Valip


1 Answers

With mongoose you can use pre and post middleware on your schemas:

personSchema.post('remove', removeLinkedDocuments);

Then in the removeLinkedDocuments callback, you can remove all linked documents:

function removeLinkedDocuments(doc) {
    // doc will be the removed Person document
    Event.remove({_id: { $in: doc.eventsAttended }})
}

Note the middleware is only called for the following methods (refer to the linked documentation for details):

  • count
  • find
  • findOne
  • findOneAndRemove
  • findOneAndUpdate
  • update

To remove the documents 'manually' in your callback, you might do

Person.findOneAndRemove({_id: req.body._id}, (err, response) => {
    // note that if you have populated the Event documents to
    // the person documents, you have to extract the id from the
    // req.body.eventsAttended object 
    Event.remove({_id: { $in: req.body.eventsAttended }}, (err, res) => {
       ...
    })
})
like image 89
DevDig Avatar answered Oct 19 '22 15:10

DevDig