在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
相关产品推荐
相关产品推荐

