在猫鼬中删除级联样式

Nic*_*ons 39 mongoose mongodb

有没有办法删除Mongoose中父级的所有子级,类似于使用MySQL的外键?

例如,在MySQL中,我将分配一个外键并将其设置为在删除时级联.因此,如果我要删除客户端,则也会删除所有应用程序和关联用户.

从顶层:

  1. 删除客户端
  2. 删除抽奖活动
  3. 删除提交

抽奖和提交都有一个client_id字段.提交的字段包含sweepstakes_id和client_id.

现在,我正在使用以下代码,我觉得必须有更好的方法.

Client.findById(req.params.client_id, function(err, client) {

    if (err)
        return next(new restify.InternalError(err));
    else if (!client)
        return next(new restify.ResourceNotFoundError('The resource you requested could not be found.'));

    // find and remove all associated sweepstakes
    Sweepstakes.find({client_id: client._id}).remove();

    // find and remove all submissions
    Submission.find({client_id: client._id}).remove();

    client.remove();

    res.send({id: req.params.client_id});

});
Run Code Online (Sandbox Code Playgroud)

Joh*_*yHK 97

这是Mongoose 'remove' 中间件的主要用例之一.

clientSchema.pre('remove', function(next) {
    // 'this' is the client being removed. Provide callbacks here if you want
    // to be notified of the calls' result.
    Sweepstakes.remove({client_id: this._id}).exec();
    Submission.remove({client_id: this._id}).exec();
    next();
});
Run Code Online (Sandbox Code Playgroud)

这样,当您调用client.remove()此中间件时,将自动调用以清除依赖项.

  • 当我将其移动到我的架构定义文件(模型)中时,效果非常好。不过,我必须将 .exec() 添加到删除调用的末尾。这没什么坏处,对吧? (2认同)
  • @JohnnyHK:只有当我们调用client.remove()时才会调用此方法.在我的应用程序中,我使用以下语句删除它:Client.findByIdAndRemove(client_id,function(err){})这个pre hook是否会被调用? (2认同)

Tal*_*wan 8

如果您的引用以其他方式存储,比如说,client有一个数组submission_ids,那么以与接受的答案类似的方式,您可以定义以下内容submissionSchema:

submissionSchema.pre('remove', function(next) {
    Client.update(
        { submission_ids : this._id}, 
        { $pull: { submission_ids: this._id } },
        { multi: true })  //if reference exists in multiple documents 
    .exec();
    next();
});
Run Code Online (Sandbox Code Playgroud)

这将从客户端的 引用数组中删除提交的 id .submission.remove()