当删除父级时,猫鼬删除子级文档引用

时间:2019-11-28 17:35:00

标签: javascript node.js mongodb mongoose

大家好,感谢您关注我的问题, 我想删除父母中引用的孩子 这是结构:

const parentSchema: = new Schema({
  name: String,
  child: { type: mongoose.Schema.Types.ObjectId, ref:'Child' },
})

const childSchema: = new Schema({
  name: String,
})

将子级保存到其自己的子级集合中,父级包含其引用。

我的处理方法如下:

parentSchema.statics.deleteByID = async function (id: string) {
  try {
    const parent = await this.findOne({ id })
    const child = await Child.findOne({_id: parent.child })

    const childDel = child && await child.remove()
    const parentDel = await parent.remove()
    
    console.log(parent, child, childDel, parentDel)

  } catch(err) {
    throw new Error(err)
  }
}

这很好用,我想知道这是否是最好的方法。

2 个答案:

答案 0 :(得分:1)

我不认为猫鼬是否内置此功能。

您能做的最好的事情就是按照here所述创建一个可移除的中间件:

顺便说一句,为了缩短现有代码,可以使用findByIdAndDelete。它返回已删除的文档,因此使用以下代码2命中数据库即可完成工作:

    const parentDel = await Parent.findByIdAndDelete(id);
    const childDel = await Child.deleteOne({_id: parentDel.child});

    console.log(parentDel, childDel);

parentDel将如下所示:

{
    "_id": "5de0114ad068f335b480925a",
    "name": "Parent 1",
    "child": "5de01144d068f335b4809259",
    "__v": 0
}

childDel将如下所示:

{
    "n": 1,
    "ok": 1,
    "deletedCount": 1
}

答案 1 :(得分:0)

我认为这是解决我的问题的最佳方法,希望它对任何人都有帮助。 我的问题是认为pre('remove')挂钩会在Class调用上触发,但仅在实例上调用。 因此,我首先使用findOne()查找要删除的实例,而不是Parent.deleteOne(),然后使用parent.remove()触发pre('remove')并删除必要的孩子... 这是一个示例:

 parentSchema.pre<ParentDocument>('remove', async function() {
  try {
    if (this.child01) {
      await Child01.deleteOne({ _id: this.child01 })
    }
    if (this.child02) {
      await Child02.deleteOne({ _id: this.child02 })
    }
  } catch(err) {
    throw new Error(err)
  }
})

parentSchema.statics.deleteByID = async function (id: string) {
  try {
    const parent = await this.findOne({ id })
    return !!(parent && await parent.remove())
  } catch(err) {
    throw new Error(err)
  }
}