如何使用mongoose(nodejs)中的聚合更新讲师的平均评分

von4xj4u  于 2022-11-13  发布在  Go
关注(0)|答案(1)|浏览(115)

这是我的教师方案

const Schema = mongoose.Schema;
const { ObjectId } = mongoose.Schema;
const instructorSchema = new Schema({
  firstName: {
    type: String,
    required: true,
  },
  lastName: {
    type: String,
    required: true,
  },
  userName: {
    type: String,
    required: true,
    unique: true,
  },
  password: {
    type: String,
    required: true,
  },
  rating:[{
    type: Number
}],
  biography: {
    type: String,
  },
  email: {
    type: String,
  },
  education: {
    type: String,
  },
  projects: {
    type: String,
  },
  reviews: {
    type: String,
  },
});
const Instructor = mongoose.model("Instructor", instructorSchema);
module.exports = Instructor;

如您所见,分级是一个数组形式的属性。

这是我在指导者的控制器文件中尝试的get方法。

const viewRating=async(req,res,next)=>{
   Instructor.aggregate([
      { $match: { "instructor" : req.params.id } },
      { $unwind: "$rating" },
      { $group : {_id : "$_id", avgRate : {  $avg : "$rating.rate" } } }
  ], function (err, result) {
      if (err) {
          console.log(err);
          return;
      }
      console.log(result);
  });

}

这是我在postman中尝试的类型
请访问:
它不停地加载。

我的路由器文件(仅与问题相关的文件)

instRouter.get("/viewRating/:id",viewRating)

my index.js(仅与问题相关的内容)

app.use("/instructor",instRouter);

我认为问题出在get方法中,但我不知道如何正确使用聚合。

toiithl6

toiithl61#

您尝试做的事情效率很低......或者说应该是这样。因为您是通过instructor进行过滤的,但是我在模式中看不到该属性,所以查询应该返回null。
但问题也在于求平均值的方式。也许我误解了什么,$match得到了整个集合,然后$unwind真的很慢
在这一点上,你解构整个数组,以重建再次计算平均。
我认为您可以将$project$avg结合起来,它们无需额外的步骤即可输出数组的平均值:

{
  "$project": {
    "rating": {
      "$avg": "$rating"
    }
  }
}

示例here
因此,您的查询应该如下所示:

Instructor.aggregate([
      { $match: { "instructor" : req.params.id } }, // your match here, maybe you have to modify
      { $project: { "rating": { "$avg": "$rating" } }
}
  ], function (err, result) {
      if (err) {
          console.log(err);
          return;
      }
      console.log(result);
  });

相关问题