有没有一种方法可以删除Mongoose中父对象的所有子对象,类似于使用MySQL外键?
例如,在MySQL中,我会分配一个外键并将其设置为cascade on delete。因此,如果我删除一个客户端,所有的应用程序和相关的用户也将被删除。
从顶层:
1.删除客户端
1.删除抽奖
1.删除提交
抽奖和提交都有一个client_id字段。Submissions有一个字段用于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});
});
6条答案
按热度按时间cl25kdpy1#
这是Mongoose的
'remove'
middleware的主要用例之一。这样,当您调用
client.remove()
时,这个中间件会自动被调用来清理依赖项。7vux5j2d2#
如果你的引用是以其他方式存储的,比如说,
client
有一个submission_ids
的数组,那么以类似于接受答案的方式,你可以在submissionSchema
上定义以下内容:这将从
submission.remove()
上的客户端的引用数组中删除提交的id。6yoyoihd3#
我注意到这里所有的答案都有一个
pre
分配给模式,而不是post
。我的解决方案是这样的(使用mongoose 6+)
根据定义,post在进程结束
pre => process => post
之后执行。现在,您可能想知道这与这里提供的其他解决方案有何不同。如果服务器错误或找不到该客户端的ID怎么办?在pre上,它会在
client
的删除过程开始之前删除所有sweeptakes
和submissions
。因此,如果出现错误,最好在client
或主文档被删除后级联删除其他文档。在这里,alert和await是可选的。但是,这对大数据很重要。这样,如果删除进程仍在进行,用户就不会得到那些“将要被删除”的级联文档数据。
最后,我可能是错的,希望这对代码中的某个人有所帮助。
rjzwgtxy4#
这是我发现的另一种方法
hjzp0vay5#
型号
密码(* 可选 *)
控制器
https://mongoosejs.com/docs/api/model.html#model_Model-remove
btxsgosb6#
与Mongoose核心一样,相关文档是用type:mongoose.Schema.Types.ObjectId和ref:'Related_Model'的组合指定的。此插件为ObjectID类型增加了两个配置选项:$through和$cascadeDelete。
$through定义了相关文档的路径,该路径是对该文档的引用。如果你有两个这样的schema:
var pagingRelations = require('paging-relations'); var fooSchema = new mongoose.Schema({ title:String,bars:[{ type:mongoose.Schema.Types.ObjectId,ref:'Bar ',$through:'foo' }] });
//应用插件fooSchema.plugin(fooingRelations);
var barSchema = new mongoose.Schema({ title:String,foo:{ type:mongoose.Schema.Types.ObjectId,ref:'Foo ' } });
//应用插件barSchema.plugin(pagingRelations);
如果在运行remove()后立即查询数据库,级联删除进程可能仍未完成。在我们的测试中,我们只需等待5秒钟,然后检查过程是否成功。