2021年使用mongoose/MongoDB中间件删除关联文档的报错问询
错误原因
Parent.updateOne is not a function由模块循环依赖导致:Node.js的CommonJS模块机制处理循环引用时,会返回未完成加载的模块导出对象,你在children.js顶部引入的Parent不是完整的Mongoose模型实例,因此无法调用模型方法。$pull语法错误:Parent模型的childrens字段存储的是直接的ObjectId数组,不是嵌套对象数组,不需要通过{_id: 目标ID}的格式匹配。- 原有
updateOne方法只会更新第一个匹配到的Parent文档,如果子文档可能关联多个父文档,需要替换为updateMany批量更新所有关联的父文档。
修正后的代码
仅需要修改children.js中的中间件逻辑即可:
//file => children.js const mongoose = require("mongoose"); // 去掉顶部引入Parent的代码,避免循环依赖 // const Parent = require("./parent"); const childrenSchema = new mongoose.Schema({ childrenId: Number, info: String, type: String, }); childrenSchema.pre('findOneAndDelete', async function(next) { console.log('trigger when middleware runs' , this.getQuery()["_id"]) ; // 中间件触发时所有模型已完成加载,通过mongoose.model动态获取Parent模型,规避循环依赖问题 const Parent = mongoose.model('Parent'); const childrenId = this.getQuery()["_id"]; // 修正$pull语法,根据需求选择updateOne/updateMany await Parent.updateMany({}, { $pull: { childrens: childrenId }}); next() }) const Children = mongoose.model("Children", childrenSchema); module.exports = Children ;
补充说明
如果确认子文档只会关联一个父文档,可将updateMany改回updateOne,性能更好。
内容的提问来源于stack exchange,提问作者relu
相关产品推荐
相关产品推荐

