How to delete in cascade in several models with mongoose?

I have these 3 models in mongoose:

TravelSchema

var travelSchema = new mongoose.Schema({
    name: String,
    description: String,
    mexican_currency_value: mongoose.Schema.Types.Decimal128
})

travelSchema.pre('deleteOne', function(next) {
    const id = this.getQuery()['_id'];
    Product.deleteMany({ travel: id }, (err, value) => {
    });
    next();    
});

ProductSchema

var productSchema = new mongoose.Schema({
    name: String,
    description: String,
    purchased_amount: Number,
    unit_price_mex: mongoose.Schema.Types.Decimal128,
    unit_price_to_sell: mongoose.Schema.Types.Decimal128,
    travel: { type: mongoose.Schema.Types.ObjectId, ref: 'Travel' }
})

InvoiceSchema

var invoiceSchema = new mongoose.Schema({
    product: productSchema,
    client: { type: mongoose.Schema.Types.ObjectId, ref: 'Client' },
    purchased_amount: Number,
    fch: String
});

Where Travel and Product have a one-to-many relationship and Product and Invoice have a one-to-many relationship. I need the following:

I have managed to eliminate all the products, but when I try to eliminate the invoices I do not obtain the ids of the Products.

invoiceSchema.pre('deleteMany', (next) => {
    console.log(this);
    // this print { n: 2, ok: 1, deletedCount: 2 }
})

Upvotes: 2

Views: 2805

Answers (1)

Akrion
Akrion

Reputation: 18515

I think you should start the other way when looking at deleting all the related docs. Like you have travel id, with it get all the products and store their id in array and then your first delete should be of the invoices where product._id: { $ in: _arrayOfProducIds }. Once that is complete then deleteMany your products since you already have their ids in the _arrayOfProducIds and lastly deal with the Travel:

travelSchema.pre('deleteOne', function(next) {
    const id = this.getQuery()['_id'];  // travel id check
    // Query to get all the product ids based on the travel id and return array for `$in`
    const productIds = this.DoYourQuery  // [productIds] check
    Invoice.deleteMany({'product._id': { $in: productIds }}, // ... etc
    Product.deleteMany({ _id': { $in: productIds }}, // ... etc
    next();    
});

I would assume you do not have a large number of products and invoices ... like thousands since then $in might be somewhat of a performance issue.

Upvotes: 1

Related Questions