这是问题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/

10-10 07:23