Next.js应用中Mongoose pre('updateOne')中间件未运行问题
Mongoose pre('updateOne')中间件未生效的解决方案
问题分析
你配置的pre('updateOne')中间件未执行且无日志输出,核心原因有两点:
- Mongoose的
updateOne中间件分文档中间件和查询中间件,默认绑定的是文档实例的updateOne()方法,若你调用的是模型静态方法Model.updateOne(),不会触发该中间件。 - 即便绑定正确,直接给
this.updatedAt赋值的写法在查询中间件里不生效,因为此时this是查询对象而非文档实例。
修复方案
方案1:修正中间件绑定与写法
若坚持使用自定义中间件,需明确绑定查询中间件并调整赋值逻辑:
// 绑定查询中间件(适配Model.updateOne()静态方法) ExampleSchema.pre("updateOne", { document: false, query: true }, function (next) { console.log("updateOne中间件执行"); // 通过set方法更新字段 this.set({ updatedAt: new Date(Date.now()) }); next(); }); // 若需同时支持文档实例的updateOne()方法,可额外绑定文档中间件 ExampleSchema.pre("updateOne", { document: true, query: false }, function (next) { this.updatedAt = new Date(Date.now()); next(); });
方案2:使用Mongoose内置timestamps选项(推荐)
Mongoose内置了timestamps功能,可自动管理createdAt和updatedAt字段,无需手动编写中间件:
const ExampleSchema = new mongoose.Schema({ // 你的其他业务字段 }, { timestamps: true // 开启自动时间戳管理 });
开启后,Mongoose会自动完成:
- 文档创建时,设置
createdAt和updatedAt为当前时间 - 调用
updateOne、findByIdAndUpdate等更新方法时,自动同步更新updatedAt
验证方式
修改后调用Model.updateOne()或文档实例的updateOne(),检查数据库中updatedAt字段是否更新,同时查看控制台是否有中间件的日志输出。
内容的提问来源于stack exchange,提问作者Ethan
相关产品推荐
相关产品推荐

