Michael Cole
Michael Cole

Reputation: 16217

Mongoose cascading deletes in same model

This is different than this and this. But they are very helpful.

Basically, I have a Topic schema. If one Topic get's deleted, I want to delete other topics. Think of a graph where deleting a node means deleting the edges.

var schema = new Schema({
  title: { type: String, required: true, trim: true },
  srcId: { type: Schema.Types.ObjectId, validate: [edgeValidator, 'Set both srcId and destId, or neither'] },
  destId: Schema.Types.ObjectId,
});

I want the 2nd mongo delete to run in the schema.pre('remove', ...)

But I don't have a model at this point. So calling .find() or .remove() doesn't work. What's the best way?

schema.pre('remove', function(next) {
  var query = '';
  var self = this;
  if (this.isEdge) {
    query = 'MATCH ()-[r:CONNECTION { mongoId: {_id} }]-() DELETE r;';
  } else {
    query = 'MATCH (n:Topic { mongoId: {_id} })-[r]-() DELETE n,r;'; 
  }
  // This is another database.   
  neo.query(query, this, function(err, data) {
    if (err) return next(err);

    if (self.isEdge) {
      return next();
    } else {
      // Now we're back to mongoose and mongodb
      // Find and remove edges from mongo
      schema.find({ mongoId: {      // <------ .find() is undefined
        $or: [
          { srcId: self._id },
          { destId: self._id }
        ]
      }}, function(err, edges) {
        edges.remove(next);
      });
    }
  });
});

Upvotes: 0

Views: 241

Answers (1)

Michael Cole
Michael Cole

Reputation: 16217

This turned out to be pretty easy.

var Model = null;

var schema = ...

module.exports = Model = mongoose.model('Topic', schema);

Then just use Model in the pre-remove. Piece of pie.

Upvotes: 1

Related Questions