这是问题https://github.com/Automattic/mongoose/issues/6224的副本。
我将一个名为FileSpace的嵌入对象创建为一个名为Space的对象数组。删除FileSpace时,永远不会调用预删除中间件(但会调用预验证中间件)
这是一个重复代码:
'use strict'; var mongoose = require('mongoose'), Schema = mongoose.Schema; mongoose.set('debug', true); /** * A file */ var FileSpaceSchema = new Schema({ fileKey: { type: String, required: true } }); // Normally called FileSpaceSchema.pre('validate', function (next) { console.log('Calling FileSpace.pre.validate me="%s"', this.fileKey); next(); }); // Never called ! FileSpaceSchema.pre('remove', function(next) { console.log(' !!! Calling FileSpace.pre.remove fileKey="%s"', this.fileKey); next(); }); let FileSpace = mongoose.model('FileSpace', FileSpaceSchema); /** * A space containing an array of files */ var SpaceDocSchema = new Schema({ label: { type: 'string', required: true }, files: [FileSpaceSchema] }); SpaceDocSchema.pre('validate', function (next) { console.log('Calling SpaceDocSchema.preValidate hook spaceDoc is "%s"', this.label); next(); }); SpaceDocSchema.pre('remove', function (next) { console.log('Calling Space.post.remove spaceDoc is "%s"', this.label); next(); }); let SpaceDoc = mongoose.model('SpaceDoc', SpaceDocSchema); console.log('--> Starting'); console.log('--> Creating a space'); let space = new SpaceDoc({ label: 'The SpaceDoc' }), removedFile; // connect to mongo mongoose.connect('mongodb://mongodbsrv/clouderialTestDB?w=1&j=true'); mongoose.connection.on('open', () => { console.log('Connection to MongoDB is effective'); space.save() .then((s) => { space = s; console.log('Created space is "%s"', s.label); console.log('--> Creating a FileSpace'); return new FileSpace({fileKey : 'fileSpace', spaceLabel:'The space label'}).save(); }) .then((fs) => { console.log('Created FileSpace is "%s"', fs.fileKey); console.log('--> Add fileSpace into SpaceDoc.files'); space.files.push(fs); space.markModified('files'); return space.save(); }) .then((s) => { space = s; console.log('Updated space is "%s", nbFiles="%d"', space.label, space.files.length); console.log('--> Remove fileSpace from space'); removedFile = space.files[0]; space.files.splice(0, 1); // space.files = []; space.markModified('files'); console.log('--> Update space without file'); return space.save(); }) .then((s) => { space = s; console.log('Updated space is "%s", nbFiles="%d"', space.label, space.files.length); console.log('--> Remove fileSpace'); return removedFile.remove(); }) .then(() => { console.log('--> Should see the call to pre.remove of FileSpace'); console.log('--> Remove space'); return space.remove(); }) .catch(console.error); }); setTimeout(() => { console.log('--> Close MongoDB connection'); mongoose.connection.close(); }, 3000);
输出如下:
$ npm start > test@0.0.1 start /datas/cld-apps/test > NODE_PATH=/home/vagrant/cld-apps/node_modules:. TZ=Europe/Paris node test.js --> Starting --> Creating a space Connection to MongoDB is effective Calling SpaceDocSchema.preValidate hook spaceDoc is "The SpaceDoc" Mongoose: spacedocs.insert({ label: 'The SpaceDoc', files: [], _id: ObjectId("5aa18e47f13311778fdc3beb"), __v: 0 }) Created space is "The SpaceDoc" --> Creating a FileSpace Calling FileSpace.pre.validate me="fileSpace" Mongoose: filespaces.insert({ fileKey: 'fileSpace', _id: ObjectId("5aa18e47f13311778fdc3bec"), __v: 0 }) Created FileSpace is "fileSpace" --> Add fileSpace into SpaceDoc.files Calling SpaceDocSchema.preValidate hook spaceDoc is "The SpaceDoc" Calling FileSpace.pre.validate me="fileSpace" Mongoose: spacedocs.update({ _id: ObjectId("5aa18e47f13311778fdc3beb"), __v: 0 }, { '$set': { files: [ { fileKey: 'fileSpace', _id: ObjectId("5aa18e47f13311778fdc3bec"), __v: 0 } ] }, '$inc': { __v: 1 } }) Updated space is "The SpaceDoc", nbFiles="1" --> Remove fileSpace from space --> Update space without file Calling SpaceDocSchema.preValidate hook spaceDoc is "The SpaceDoc" Mongoose: spacedocs.update({ _id: ObjectId("5aa18e47f13311778fdc3beb"), __v: 1 }, { '$set': { files: [] }, '$inc': { __v: 1 } }) Updated space is "The SpaceDoc", nbFiles="0" --> Remove fileSpace --> Should see the call to pre.remove of FileSpace --> Remove space Calling Space.post.remove spaceDoc is "The SpaceDoc" Mongoose: spacedocs.remove({ _id: ObjectId("5aa18e47f13311778fdc3beb") }, {}) --> Close MongoDB connection
预期的行为是什么? 我们应该看到日志行:
!!! Calling FileSpace.pre.remove fileKey
请提及您的node.js,mongoose和MongoDB版本。 节点9.5.0,Mongoose 5.0.9,MongoDB 3.6.3,Mongo驱动程序:3.0.3
编辑:如果我删除了space.files.push(fs)行,则正确调用中间件。仅当fileSpace放入空间对象数组时才会发生pb。
答案 0 :(得分:0)
文档说:
Model.remove()-此方法将删除命令直接发送到 MongoDB,不涉及Mongoose文档。因为没有猫鼬 涉及文档,不执行任何中间件(挂钩)。