Description
Do you want to request a feature or report a bug?
Bug
What is the current behavior?
Pre-remove middleware is not called when removing an item from an array of subdocuments. According to #6224, this seemed to work with Mongoose <5.0.0. @vkarpov15 asked @georgehess to open a new issue on this in the same #6224, though it appears not to have happened, thus I'm running it up the flagpole.
This behaviour presents a problem for me because I need to know when a document is removed from an array, so that a corresponding cache entry can be deleted. Unfortunately, modifiedPaths doesn't provide enough context to tell me when something is removed, only that something happened. I can, of course, clear the cache entry manually from outside of my Mongoose code, but this seems like a less-than-elegant solution.
If the current behavior is a bug, please provide the steps to reproduce.
const mongoose = require('mongoose');
const SubSchema = mongoose.Schema({
myValue: {
type: String
}
}, {});
SubSchema.pre('remove', async function() {
console.log('Subdoc got removed!')
});
const Schema = mongoose.Schema({
foo: {
type: String,
required: true
},
mySubdoc: {
type: [SubSchema],
required: true
}
}, {minimize: false, collection: 'test'});
const Model = mongoose.model('TestModel', Schema);
const initMongoose = async () => {
const mongooseUrl = `mongodb://user:pass@dbhost:27017/test`;
try {
await mongoose.connect(mongooseUrl, {
useUnifiedTopology: true,
useNewUrlParser: true,
promiseLibrary: global.Promise,
useFindAndModify: false
});
}
catch (err) {
console.error(err);
process.exit(1);
}
console.log('Connected');
};
const test = async () => {
await Model.deleteMany({}); // remove all existing documents
const newModel = {
foo: 'bar',
mySubdoc: [{myValue: 'some value'}]
};
const document = await Model.create(newModel);
console.log('Created document');
console.log('document:', document);
console.log('Removing subDocument');
document.mySubdoc[0].remove();
console.log('Saving document');
await document.save().catch( (error) => {
console.error(error);
process.exit(1);
});
console.log('document:', document);
console.log(`Notice that SubSchema.pre('remove') never ran`);
};
const main = async () => {
await initMongoose();
await test();
process.exit(0);
};
main();
Output from the above is:
Connected
Created document
document: {
_id: 601831bcddc22e01c640d6b6,
foo: 'bar',
mySubdoc: [ { _id: 601831bcddc22e01c640d6b7, myValue: 'some value' } ],
__v: 0
}
Removing subDocument
Saving document
document: { _id: 601831bcddc22e01c640d6b6, foo: 'bar', mySubdoc: [], __v: 1 }
Notice that SubSchema.pre('remove') never ran
What is the expected behavior?
Pre-remove hooks should run when removing sub-documents.
What are the versions of Node.js, Mongoose and MongoDB you are using? Note that "latest" is not a version.
Mongoose 5.11.14
Node.js 15.5.1
MongoDB 4.4.1