You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在NestJS中使用Mongoose实现级联删除?

在Nest.js中实现学生删除时级联删除选课记录的方案

以下是两种可靠的实现方式,适配不同的删除调用场景:

方式一:文档实例级中间件(pre('remove'))

该方案针对文档实例的remove()方法生效,需确保服务层先查询到学生文档再执行删除。

步骤1:导入依赖

在Student Schema文件顶部,引入Enrollment模型及mongoose核心:

import { Enrollment } from './enrollment.schema'; // 替换为你的实际文件路径
import mongoose from 'mongoose';

步骤2:添加级联删除中间件

在StudentSchema定义完成后,追加以下中间件逻辑:

StudentSchema.pre('remove', async function(next) {
  // this 指向当前待删除的Student文档实例
  await mongoose.model(Enrollment.name).deleteMany({
    student: this._id
  });
  next();
});

服务层调用示例

在学生服务类中,使用文档实例的remove()方法触发中间件:

// student.service.ts
async deleteStudent(id: string) {
  const student = await this.studentModel.findById(id);
  if (!student) {
    throw new NotFoundException('学生不存在');
  }
  await student.remove(); // 触发pre('remove')级联删除
  return { message: '学生及关联选课记录已删除' };
}

方式二:模型级中间件(pre('deleteOne'))

如果习惯使用模型的deleteOne/findByIdAndDelete方法,可通过该方案覆盖文档实例和模型调用两种场景:

添加双场景中间件到StudentSchema

// 文档实例级deleteOne触发的中间件
StudentSchema.pre('deleteOne', { document: true, query: false }, async function(next) {
  await mongoose.model(Enrollment.name).deleteMany({ student: this._id });
  next();
});

// 模型级deleteOne触发的中间件(如StudentModel.deleteOne({_id: id}))
StudentSchema.pre('deleteOne', { document: false, query: true }, async function(next) {
  const query = this.getQuery();
  await mongoose.model(Enrollment.name).deleteMany({ student: query._id });
  next();
});

服务层调用示例

此时两种删除方式均可触发级联:

// 方式1:模型直接调用deleteOne
async deleteStudent(id: string) {
  const result = await this.studentModel.deleteOne({ _id: id });
  if (result.deletedCount === 0) {
    throw new NotFoundException('学生不存在');
  }
  return { message: '学生及关联选课记录已删除' };
}

// 方式2:文档实例调用deleteOne
async deleteStudent(id: string) {
  const student = await this.studentModel.findById(id);
  if (!student) {
    throw new NotFoundException('学生不存在');
  }
  await student.deleteOne();
  return { message: '学生及关联选课记录已删除' };
}

关键注意事项

  • 确保Enrollment模型已在Nest模块中正确注册,否则mongoose.model(Enrollment.name)会抛出未找到模型的错误。
  • 若业务需要数据强一致性,需将级联删除操作纳入Mongoose事务中。
  • 区分文档中间件与查询中间件的作用范围,根据实际使用的删除方法选择对应中间件类型。

内容的提问来源于stack exchange,提问作者Zoodek

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.08 04:42:54