new*_*bie 6 javascript mongoose mongodb node.js express
我尝试了所有与使用 node.js 在 MongoDB 中删除引用文档相关的堆栈溢出解决方案。但是他们中的大多数要么有不推荐使用的方法的解决方案,其中一些根本不起作用。
我有两个模型,Parent并且Child有one-to-many关系。父文档包含一组引用的子文档 ID,如下面的架构所示。
//file => parent.js
const parentSchema = new mongoose.Schema({
parentName: {
type: String,
},
childrens : [
{
type: mongoose.Schema.Types.ObjectId,
ref: 'Children'
}
]
});
const Parent = mongoose.model("Parent", parentSchema);
module.exports = Parent ;
Run Code Online (Sandbox Code Playgroud)
下一个文件具有成功触发的children带有childrenSchema.pre()中间件或钩子的模型-
//file => children.js
const mongoose = require("mongoose");
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"]) ;
const childrenId = new mongoose.Types.ObjectId(this.getQuery()["_id"])
await Parent.updateOne({} , { $pull: { childrens: { _id: childrenId }}});
next()
})
const Children = mongoose.model("Children", childrenSchema);
module.exports = Children ;
Run Code Online (Sandbox Code Playgroud)
现在,最后这是我调用以删除childrenId. 我有很多错误,但主要是说这Parent.updateOne()不是上述文件中的函数。但是当执行下面的路由时,中间件成功触发。
// route which performs delete action and triggers mongoose middleware
router.delete('/delete/instance' , async(req,res) => {
const childrenId = new mongoose.Types.ObjectId('612cd0d8f9553c9f243db691')
const deletedInstance = await Children.findOneAndDelete(
{ _id: childrenId}
)
res.json(deletedInstance)
})
Run Code Online (Sandbox Code Playgroud)
在写这个问题之前,我花了一整天的时间来弄清楚这一点,任何帮助将不胜感激。谢谢你。
请注意,您尝试updateOne()在不使用过滤器选项的情况下执行。对于逻辑本身,为什么不把它放在路由器内部:
const Parent = require("./parent");
router.delete('/delete/instance' , async (req,res) => {
await Parent.updateOne({ childrens: '612cd0d8f9553c9f243db691' }, { $pull: { childrens: '612cd0d8f9553c9f243db691' }})
const deletedInstance = await Children.findOneAndDelete({ _id: '612cd0d8f9553c9f243db691'})
res.json(deletedInstance)
})
Run Code Online (Sandbox Code Playgroud)