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

在Mongoose deleteOne后置钩子中调用静态方法时触发错误

解决Mongoose deleteOne后置钩子调用静态方法报错问题

问题原因

在deleteOne的后置钩子中,this的指向分两种场景:

  • 调用**文档实例的deleteOne()**时,this指向文档实例,this.constructor是对应的数据模型;
  • 调用**模型的deleteOne()**时,this指向Query查询对象,此时this.constructor是Query的构造函数,自然找不到你定义的calculateAverageRating静态方法。

这就是报错this.constructor.calculateAverageRating is not a function的核心原因。

解决方案

方案1:用this.model调用静态方法

Mongoose的文档实例和Query对象都自带model属性,指向当前对应的数据模型。用它替代this.constructor,能兼容两种调用场景:

reviewSchema.statics.calculateAverageRating = async function (productId) {
  console.log(productId);
};

reviewSchema.post("deleteOne", async function () {
  // 区分文档实例和Query对象,获取productId
  const productId = this.product ? this.product : this.getQuery().product;
  await this.model.calculateAverageRating(productId);
});

方案2:直接引用已定义的模型

如果你已经明确创建了Review模型,也可以直接用模型名调用静态方法:

const mongoose = require('mongoose');
const reviewSchema = new mongoose.Schema({
  // 你的Schema字段定义
  product: { type: mongoose.Schema.Types.ObjectId, ref: 'Product' }
});

reviewSchema.statics.calculateAverageRating = async function (productId) {
  console.log(productId);
};

// 先创建模型
const Review = mongoose.model('Review', reviewSchema);

// 再定义后置钩子
reviewSchema.post("deleteOne", async function () {
  const productId = this.product ? this.product : this.getQuery().product;
  await Review.calculateAverageRating(productId);
});

关键说明

代码中通过this.product判断当前场景:如果是文档调用deleteOne,this是文档实例,会有product字段;如果是模型调用deleteOne,this是Query对象,需要用this.getQuery()获取查询条件,从中提取productId(这里假设你的查询条件是{ product: productId },如果查询字段名不同,需要对应调整)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 12:45:20