首页 > 解决方案 > 无法使用 Mongoose 中间件删除 Mongoose 文档

问题描述

我正在使用具有以下设计的 Typescript + Mongoose + GraphQL

我正在尝试编写一个猫鼬中间件,如果我要删除特定任务,它将帮助我删除与特定任务相关的评论

目前,我可以通过调用 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;

评论

import * as mongoose from "mongoose";

const Schema = mongoose.Schema;

const commentSchema = new Schema(
  {
    review: {
      type: String,
      required: true,
    },
    task: {
      type: Schema.Types.ObjectId,
      ref: "Task",
    },
    user: {
      type: Schema.Types.ObjectId,
      ref: "User",
    },
  },
  {
    timestamps: true,
  }
);

const Comment = mongoose.model("Comment", commentSchema);

export default Comment;

用户

import * as mongoose from "mongoose";

import hobbySchema from "./Hobby";

const Schema = mongoose.Schema;

const userSchema = new Schema(
  {
    name: {
      type: String,
    },
    email: {
      type: String,
      required: true,
    },
    password: {
      type: String,
    },
    hobbies: [hobbySchema],
    tasks: [
      {
        type: Schema.Types.ObjectId,
        ref: "Task",
      },
    ],
  },
  {
    timestamps: true,
  }
);

const User = mongoose.model("User", userSchema);

export default User;

标签: mongodbmongoose

解决方案


请参阅文档findByIdAndRemove只需触发findOneAndRemove()中间件,因此您需要将中间件更改为findOneAndRemove. 但是findOneAndRemove查询中间件,所以this在中间件功能中指的是查询,而不是文档。要使其工作,您需要进行一些更改:

  1. 使用findOneAndRemove中间件。
  2. 使用post而不是pre因为使用pre,您无法获取文档。
  3. 将引用文档的另一个参数传递给函数。

最终代码将如下所示:

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

推荐阅读