1

当我执行这个模型时,我得到了错误。请解决这个问题。这个问题让我很头疼。反对使用“这里的内容,这里的内容”,使它看起来像可读的英语,许多桌面出版包和网页编辑器现在使用“Lorem Ipsum”作为他们的默认模型文本,搜索“Lorem Ipsum”将发现许多网络网站仍处于起步阶段。多年来,各种版本不断发展。

const mongoose = require("mongoose");
const Product = require("./shopingModel");

const reviewSchema = new mongoose.Schema({
  createdAt: {
    type: Date,
    default: Date.now(),
  },
  review: {
    type: String,
    required: [true, "A review should not be empty"],
  },
  rating: {
    type: Number,
    min: [1, "rating shount below 1"],
    max: [5, "rating must be below 5.0"],
  },
  user: {
    type: mongoose.Schema.ObjectId,
    ref: "User",
    required: [true, "A review must belong a user"],
  },
  product: {
    type: mongoose.Schema.ObjectId,
    ref: "Product",
    required: [true, "A review must belong a product"],
  },
});

reviewSchema.pre(/^findOne/, function (next) {
  this.populate("user", "name").populate("product", "title price");

  next();
});

reviewSchema.statics.calcAverageRatings = async function (productId) {
  const stats = await this.aggregate([
    {
      $match: { product: productId },
    },
    {
      $group: {
        _id: "$product",
        numRating: { $sum: 1 },
        avgRating: { $avg: "$rating" },
      },
    },
  ]);
  await Product.findByIdAndUpdate(productId, {
    ratingsAverage: stats[0].avgRating,
    ratingsQuantity: stats[0].numRating,
  });
};

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

reviewSchema.pre(/^findOneAnd/, async function (next) {
  this.r = await this.findOne();
  // console.log(this.r);
  next();
});

reviewSchema.post(/^findOneAnd/, async function () {
  // await this.findOne(); does NOT work here, query has already executed
  const model = this.r.constructor;
  await model.calcAverageRatings(this.r.tour);
});

const Review = mongoose.model("Review", reviewSchema);

module.exports = Review;

当我在中间件上运行 calcAverageRatings 然后我得到了这个

"status": "error",
"error": {
    "originalStack": "Error\n    at model.Query._wrappedThunk [as _findOne] (C:\\Users\\grixx\\Desktop\\Practice\\node_modules\\mongoose\\lib\\helpers\\query\\wrapThunk.js:25:28)\n    at C:\\Users\\grixx\\Desktop\\Practice\\node_modules\\kareem\\index.js:279:20\n    at _next (C:\\Users\\grixx\\Desktop\\Practice\\node_modules\\kareem\\index.js:103:16)\n    at C:\\Users\\grixx\\Desktop\\Practice\\node_modules\\kareem\\index.js:508:38\n    at processTicksAndRejections (internal/process/task_queues.js:77:11)",
    "status": "error",
    "statusCode": 500
},
"message": "Query was already executed: Review.findOne({ _id: new ObjectId(\"615d82ac971aae7627c5a1b9...",
"stack": "MongooseError: Query was already executed: Review.findOne({ _id: new ObjectId(\"615d82ac971aae7627c5a1b9...\n    at model.Query._wrappedThunk [as _findOneAndDelete] (C:\\Users\\grixx\\Desktop\\Practice\\node_modules\\mongoose\\lib\\helpers\\query\\wrapThunk.js:21:19)\n    at C:\\Users\\grixx\\Desktop\\Practice\\node_modules\\kareem\\index.js:279:20\n    at _next (C:\\Users\\grixx\\Desktop\\Practice\\node_modules\\kareem\\index.js:103:16)\n    at C:\\Users\\grixx\\Desktop\\Practice\\node_modules\\kareem\\index.js:508:38\n    at processTicksAndRejections (internal/process/task_queues.js:77:11)"
4

1 回答 1

1

使用 this.r = await this.clone().findOne(); 代替 this.r = await this.findOne();

于 2021-11-03T12:24:07.630 回答