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

如何在NestJS Mongoose的pre-save钩子中访问其他Schema?

在NestJS中通过Mongoose的pre-save钩子操作另一张数据表

要在Mongoose的pre-save事件钩子中操作另一张表,核心是正确获取目标模型、保留钩子的this指向,并处理异步操作,以下是具体实现步骤和示例:

关键注意事项

  • 不能用箭头函数定义钩子:箭头函数会绑定外部上下文,导致无法通过this访问当前待保存的文档。
  • 必须处理异步逻辑:数据库操作是异步的,钩子函数需使用async/await或返回Promise,确保操作完成后再执行后续保存流程。
  • 按需触发操作:用isModified()判断字段是否变更,避免每次保存都执行冗余的数据库操作。

完整示例

假设我们有两个数据表:User和Order,需求是当User的lastOrderId字段更新时,同步更新对应Order的userUpdatedAt字段。

1. 定义Schema并注册模型

首先在NestJS模块中注册两个Schema对应的Model:

// user.module.ts
import { Module } from '@nestjs/common';
import { MongooseModule } from '@nestjs/mongoose';
import { UserSchema } from './user.schema';
import { OrderSchema } from './order.schema';

@Module({
  imports: [
    MongooseModule.forFeature([
      { name: 'User', schema: UserSchema },
      { name: 'Order', schema: OrderSchema },
    ]),
  ],
})
export class UserModule {}

2. 在pre-save钩子中操作另一张表

在UserSchema的pre-save钩子中,获取Order模型并执行更新操作:

// user.schema.ts
import * as mongoose from 'mongoose';
import { Order } from './order.schema';

export const UserSchema = new mongoose.Schema({
  name: String,
  email: String,
  lastOrderId: mongoose.Schema.Types.ObjectId,
});

// 使用普通函数定义钩子,保留this指向
UserSchema.pre('save', async function (next) {
  const currentUser = this;

  // 仅当lastOrderId字段发生变化时执行更新
  if (currentUser.isModified('lastOrderId')) {
    // 获取已注册的Order模型
    const OrderModel = mongoose.connection.model<Order>('Order');

    // 执行更新操作
    await OrderModel.findOneAndUpdate(
      { _id: currentUser.lastOrderId },
      { $set: { userUpdatedAt: new Date() } },
      { new: true } // 返回更新后的文档(可选)
    );
  }

  // 调用next()继续执行保存流程
  next();
});

3. 定义OrderSchema(示例)

// order.schema.ts
import * as mongoose from 'mongoose';

export const OrderSchema = new mongoose.Schema({
  productName: String,
  amount: Number,
  userUpdatedAt: Date,
});

export type Order = mongoose.Document & {
  productName: string;
  amount: number;
  userUpdatedAt: Date;
};

额外说明

  • 如果需要在钩子中处理错误,可以在try/catch块中捕获异常,并将错误传递给next(err),中断保存流程。
  • 若目标模型未被注册,mongoose.connection.model()会抛出错误,确保所有用到的模型都已通过MongooseModule.forFeature注册到NestJS模块中。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.16 06:20:54