这是问题https://github.com/Automattic/mongoose/issues/6224的副本。
我将名为FileSpace的Embedded对象创建到名为Space的对象数组中。删除FileSpace时,永远不会调用预删除中间件(但会调用预验证中间件)
这是一个复制代码:
“使用严格”;
var mongoose = require('mongoose'),
架构= mongoose.Schema;
mongoose.set('debug',true);
/ **
* 一份文件
* /
var FileSpaceSchema = new Schema({
fileKey:{
类型:字符串,
必填:true
}
});
//通常称为
FileSpaceSchema.pre('validate',function(next){
console.log('正在调用FileSpace.pre.validate me =“%s”',this.fileKey);
下一个();
});
//从未致电!
FileSpaceSchema.pre('remove',function(next){
console.log('!!!调用FileSpace.pre.remove fileKey =“%s”',this.fileKey);
下一个();
});
让FileSpace = mongoose.model('FileSpace',FileSpaceSchema);
/ **
*包含文件数组的空间
* /
var SpaceDocSchema = new Schema({
标签: {
类型:“字符串”,
必填:true
},
文件:[FileSpaceSchema]
});
SpaceDocSchema.pre('validate',function(next){
console.log('调用SpaceDocSchema.preValidate钩子spaceDoc是“%s”',this.label);
下一个();
});
SpaceDocSchema.pre('remove',function(next){
console.log('Calling Space.post.remove spaceDoc is“%s”',this.label);
下一个();
});
让SpaceDoc = mongoose.model('SpaceDoc',SpaceDocSchema);
console.log('->开始');
console.log('->创建空间');
令space = new SpaceDoc({
标签:“ SpaceDoc”
}),
removeFile;
//连接到mongo
mongoose.connect('mongodb:// mongodbsrv / clouderialTestDB?w = 1&j = true');
mongoose.connection.on('open',()=> {
console.log('与MongoDB的连接有效');
space.save()
.then((s)=> {
space = s;
console.log('创建的空间为“%s”',s.label);
console.log('->创建文件空间');
返回新的FileSpace({fileKey:'fileSpace',spaceLabel:'space label'})。save();
})
.then((fs)=> {
console.log('创建的FileSpace为“%s”',fs.fileKey);
console.log('->将fileSpace添加到SpaceDoc.files');
space.files.push(fs);
space.markModified('files');
返回space.save();
})
.then((s)=> {
space = s;
console.log('更新的空间为“%s”,nbFiles =“%d”',space.label,space.files.length);
console.log('->从空间删除fileSpace');
removeFile = space.files [0];
space.files.splice(0,1);
// space.files = [];
space.markModified('files');
console.log('->更新没有文件的空间');
返回space.save();
})
.then((s)=> {
space = s;
console.log('更新的空间为“%s”,nbFiles =“%d”',space.label,space.files.length);
console.log('->删除fileSpace');
返回removeFile.remove();
})
.then(()=> {
console.log('->应该看到对FileSpace的pre.remove的调用');
console.log('->删除空间');
返回space.remove();
})
.catch(console.error);
});
setTimeout(()=> {
console.log('->关闭MongoDB连接');
mongoose.connection.close();
},3000);
输出如下:
$ npm开始
> [email protected]开始/ datas / cld-apps / test
> NODE_PATH = / home / vagrant / cld-apps / node_modules :。 TZ =欧洲/巴黎节点test.js
->开始
->创建空间
与MongoDB的连接有效
调用SpaceDocSchema.preValidate钩子spaceDoc是“ The SpaceDoc”
猫鼬:spacedocs.insert({标签:“ SpaceDoc”,文件:[],_ id:ObjectId(“ 5aa18e47f13311778fdc3beb”),__ v:0})
创建的空间是“ SpaceDoc”
->创建文件空间
调用FileSpace.pre.validate me =“ fileSpace”
猫鼬:filespaces.insert({fileKey:'fileSpace',_id:ObjectId(“ 5aa18e47f13311778fdc3bec”),__v:0})
创建的FileSpace是“ fileSpace”
->将fileSpace添加到SpaceDoc.files
调用SpaceDocSchema.preValidate钩子spaceDoc是“ The SpaceDoc”
调用FileSpace.pre.validate me =“ fileSpace”
猫鼬:spacedocs.update({_id:ObjectId(“ 5aa18e47f13311778fdc3beb”),__v:0},{'$ set':{files:[{fileKey:'fileSpace',_id:ObjectId(“ 5aa18e47f13311778fdc3bec”),__v:0 }]},'$ inc':{__v:1}})
更新的空间为“ The SpaceDoc”,nbFiles =“ 1”
->从空间删除fileSpace
->更新没有文件的空间
调用SpaceDocSchema.preValidate钩子spaceDoc是“ The SpaceDoc”
猫鼬:spacedocs.update({_id:ObjectId(“ 5aa18e47f13311778fdc3beb”),__v:1},{'$ set':{文件:[]},'$ inc':{__v:1}})
更新的空间为“ The SpaceDoc”,nbFiles =“ 0”
->删除文件空间
->应该看到对FileSpace的pre.remove的调用
->删除空间
调用Space.post.remove spaceDoc是“ The SpaceDoc”
猫鼬:spacedocs.remove({_id:ObjectId(“ 5aa18e47f13311778fdc3beb”)},{})
->关闭MongoDB连接
预期的行为是什么?
我们应该看到日志行:
!!!调用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。
最佳答案
该文件说:
Model.remove()-此方法将删除命令直接发送到
MongoDB,不涉及Mongoose文档。因为没有猫鼬
涉及文档,不执行任何中间件(挂钩)。
链接:
[https://mongoosejs.com/docs/api.html]
关于node.js - Mongoose数组中对象的pre.remove中间件永远不会被调用,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/49188586/