如何用Mongoose Aggregate计算讲师平均评分并解决接口无限加载问题
问题分析与修复方案
你的代码存在三个核心问题,导致请求无限加载且聚合逻辑失效:
1. 未向客户端返回响应
控制器仅在控制台打印结果或错误,但从未通过res对象给客户端发送响应,导致请求一直处于挂起状态。
2. 聚合匹配字段错误
Schema中不存在instructor字段,匹配讲师ID应使用_id;同时req.params.id是字符串类型,需要转换为MongoDB的ObjectId才能匹配文档的_id。
3. 平均值计算字段错误
你的rating是数字数组,$unwind拆分后每个元素就是数字,计算平均值时应直接用$rating,而非$rating.rate(Schema里的rating元素没有rate属性)。
修正后的控制器代码
const { ObjectId } = require('mongoose').Types; const viewRating = async (req, res, next) => { try { const result = await Instructor.aggregate([ { $match: { _id: new ObjectId(req.params.id) } }, { $unwind: "$rating" }, { $group: { _id: "$_id", avgRate: { $avg: "$rating" } } } ]); if (result.length === 0) { return res.status(404).json({ message: "未找到该讲师的评分数据" }); } res.status(200).json({ averageRating: result[0].avgRate }); } catch (err) { console.log(err); res.status(500).json({ error: "计算评分平均值失败" }); } };
额外优化建议
- 若讲师
rating数组为空,$unwind会过滤掉该文档,可添加preserveNullAndEmptyArrays: true选项保留空数组文档,再处理平均值为0或提示无评分:{ $unwind: { path: "$rating", preserveNullAndEmptyArrays: true } } - 给Schema的
rating数组设置默认值[],避免出现undefined:rating: [{ type: Number }], default: []
内容的提问来源于stack exchange,提问作者Kariman Zain
相关产品推荐
相关产品推荐

