使用 mongoose/MongoDB 中间件删除引用的文档(2021 年)

new*_*bie 6 javascript mongoose mongodb node.js express

我尝试了所有与使用 node.js 在 MongoDB 中删除引用文档相关的堆栈溢出解决方案。但是他们中的大多数要么有不推荐使用的方法的解决方案,其中一些根本不起作用。

我有两个模型,Parent并且Childone-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)

在写这个问题之前,我花了一整天的时间来弄清楚这一点,任何帮助将不胜感激。谢谢你。

Nen*_*vic 0

请注意,您尝试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)