从mongoose post hook方法调用Mongoose静态方法时出错

vu8f3i0k  于 2023-08-06  发布在  Go
关注(0)|答案(1)|浏览(77)

我尝试从mongoose 'deleteOne' post hook方法调用mongoose静态方法。但在这样做的时候,我得到下面的错误:this.constructor.calculateAverageRating不是函数

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

reviewSchema.post("deleteOne", async function () {
  await this.constructor.calculateAverageRating(this.product);
});

字符串

xu3bshqb

xu3bshqb1#

查询中间件
注意:Mongoose与schema.pre('remove')不同,默认在Query#updateOne()Query#deleteOne()上注册updateOnedeleteOne中间件。这意味着doc.updateOne()Model.updateOne()都会触发updateOne钩子,但this引用的是查询,而不是文档。要将updateOnedeleteOne中间件注册为文档中间件,请使用schema.pre('updateOne', { document: true, query: false })

calculateAverageRating是Model类上的静态方法,不是Query类示例上的。你可以通过mongoose.model('ModelName')方法得到模型类。

import mongoose, { Query } from 'mongoose';
import { config } from '../../config';

mongoose.set('debug', true);
console.log(mongoose.version);

const reviewSchema = new mongoose.Schema({});
reviewSchema.statics.calculateAverageRating = async function (productId) {
    console.log('productId: ', productId);
};
reviewSchema.post('deleteOne', async function () {
    const Model = mongoose.model('Review');
    // @ts-ignore
    await Model.calculateAverageRating('1');
    console.log('this: ', this instanceof Query, this.constructor === Query);
});
const Review = mongoose.model('Review', reviewSchema);

(async function main() {
    try {
        await mongoose.connect(config.MONGODB_URI);
        // seed
        const [r1] = await Review.create([{}, {}]);
        // test
        await Review.deleteOne({ _id: r1?._id });
    } catch (error) {
        console.error(error);
    } finally {
        await mongoose.connection.close();
    }
})();

字符串
日志:

7.3.4
Mongoose: reviews.insertOne({ _id: ObjectId("64b7608b39d77645ced9b411"), __v: 0 }, {})
Mongoose: reviews.insertOne({ _id: ObjectId("64b7608b39d77645ced9b412"), __v: 0 }, {})
Mongoose: reviews.deleteOne({ _id: ObjectId("64b7608b39d77645ced9b411") }, {})
productId:  1
this:  true true

文档中间件

要将updateOnedeleteOne中间件注册为文档中间件,请使用schema.pre('updateOne', { document: true, query: false })
在文档中间件函数中,this引用文档。要访问模型,请使用this.constructor

import mongoose from 'mongoose';
import { config } from '../../config';

mongoose.set('debug', true);
console.log(mongoose.version);

const reviewSchema = new mongoose.Schema({});
reviewSchema.statics.calculateAverageRating = async function (productId) {
    console.log('productId: ', productId);
};
reviewSchema.post('deleteOne', { document: true, query: false }, async function () {
    // @ts-ignore
    await this.constructor.calculateAverageRating('1');
    console.log('this: ', this instanceof mongoose.Document, this.constructor === mongoose.model('Review'));
});
const Review = mongoose.model('Review', reviewSchema);

(async function main() {
    try {
        await mongoose.connect(config.MONGODB_URI);
        // seed
        const [r1] = await Review.create([{}, {}]);
        // test
        await r1?.deleteOne();
    } catch (error) {
        console.error(error);
    } finally {
        await mongoose.connection.close();
    }
})();


日志:

7.3.4
Mongoose: reviews.insertOne({ _id: ObjectId("64b7621b4318463c330204f9"), __v: 0 }, {})
Mongoose: reviews.insertOne({ _id: ObjectId("64b7621b4318463c330204fa"), __v: 0 }, {})
Mongoose: reviews.deleteOne({ _id: ObjectId("64b7621b4318463c330204f9") }, { session: null })
productId:  1
this:  true true

相关问题