Mongodb 无法使用Mongoose中间件删除Mongoose文档

Mongodb 无法使用Mongoose中间件删除Mongoose文档,mongodb,mongoose,Mongodb,Mongoose,我使用的是Typescript+Mongoose+GraphQL,它有以下设计 使用者 任务 评论 我正在尝试编写一个mongoose中间件,如果我要删除特定任务,它将帮助我删除与特定任务相关的注释 目前,我可以通过调用findByIdAndRemove来删除特定任务,但是,我的mongoose中间件无法工作,因为它无法“级联”删除与我已删除的特定任务相关的注释 有人能帮我指出哪里出了错吗?谢谢 下面是我的模型 任务 import { Document, Schema, model,

我使用的是Typescript+Mongoose+GraphQL,它有以下设计

  • 使用者
    • 任务
      • 评论
我正在尝试编写一个mongoose中间件,如果我要删除特定任务,它将帮助我删除与特定任务相关的注释

目前,我可以通过调用findByIdAndRemove来删除特定任务,但是,我的mongoose中间件无法工作,因为它无法“级联”删除与我已删除的特定任务相关的注释

有人能帮我指出哪里出了错吗?谢谢

下面是我的模型

任务

import { Document, Schema, model, Types } from "mongoose";

const taskSchema = new Schema(
  {
    name: {
      type: String,
      required: true,
    },
    completed: {
      type: Boolean,
      default: false,
      required: true,
    },
    comments: [
      {
        type: Schema.Types.ObjectId,
        ref: "Comment",
      },
    ],
    user: {
      type: Schema.Types.ObjectId,
      ref: "User",
    },
  },
  {
    timestamps: true,
  }
);

interface ITaskSchema extends Document {
  name: string;
  completed: boolean;
  comments: Types.Array<Object>;
  user: Types.ObjectId;
}

taskSchema.pre<ITaskSchema>("remove", function (next) {
  const Comment = model("Comment");
  Comment.remove({ _id: { $in: this.comments } }).then(() => next());
});

const Task = model<ITaskSchema>("Task", taskSchema);

export default Task;

使用者

请参阅,
findbyiandremove
just trigger
findOneAndRemove()
中间件,因此您需要将中间件更改为
findOneAndRemove
。但是
findOneAndRemove
查询中间件所以
中间件函数中的这个
指的是查询,而不是文档。要使其工作,您需要进行一些更改:

  • 使用
    findOneAndRemove
    中间件
  • 使用
    post
    而不是
    pre
    ,因为使用
    pre
    ,您无法获取文档
  • 将引用文档的另一个参数传递给函数
  • 最终代码如下所示:

    taskSchema.post<ITaskSchema>("findOneAndRemove", function (task, next) {
      const Comment = model("Comment");
      Comment.remove({ _id: { $in: task.comments } }).then(() => next());
    });
    
    taskSchema.post(“findOneAndRemove”,函数(任务,下一步){
    常量注释=模型(“注释”);
    remove({u id:{$in:task.comments}});
    });
    
    感谢库勒恩戈,现在它可以完美地工作了!下面是mongoose中间件的最终代码

    taskSchema.post<ITaskSchema>("findOneAndRemove", async function (task, next) {
      const Comment = model("Comment");
      const User = model("User");
      await User.updateMany({ tasks: task._id }, { $pull: { tasks: task._id } });
      await Comment.remove({ _id: { $in: task.comments } });
      next();
    });
    
    taskSchema.post(“findOneAndRemove”),异步函数(任务,下一步){
    常量注释=模型(“注释”);
    const User=模型(“用户”);
    wait User.updateMany({tasks:task.\u id},{$pull:{tasks:task.\u id}});
    wait Comment.remove({u id:{$in:task.comments}});
    next();
    });
    
    非常感谢@cuongle Ngoc!它工作得很好。介意我把这个话题再扩展一点吗。该脚本可以完美地删除任务和特定于任务的注释。然而,我意识到在我的用户集合中,我的User.tasks下仍然有一个taskid数组。我是否可以使用相同的中间件“向上”访问用户模型以提取那些被禁用的TaskID?我已经添加了用户模型,以防您需要查看。非常感谢,您可以使用
    User.updateMany({tasks:task.\u id},{$pull:{tasks:task.\u id}})来完成它。
    taskSchema.post<ITaskSchema>("findOneAndRemove", function (task, next) {
      const Comment = model("Comment");
      Comment.remove({ _id: { $in: task.comments } }).then(() => next());
    });
    
    taskSchema.post<ITaskSchema>("findOneAndRemove", async function (task, next) {
      const Comment = model("Comment");
      const User = model("User");
      await User.updateMany({ tasks: task._id }, { $pull: { tasks: task._id } });
      await Comment.remove({ _id: { $in: task.comments } });
      next();
    });