Spring Boot中使用MongoRepository计算Mongo集合指定用户rating平均值
问题原因
原有代码存在以下几处问题导致无法正常运行:
- 缺少
$match阶段过滤指定userId,直接对全集合所有用户分组计算,既不符合需求也会产生全表扫描的性能问题 - 聚合表达式语法错误,
$rating未用引号包裹,且未绑定方法入参到聚合条件中 - 聚合结果默认返回BSON文档结构,无法直接映射为double类型返回值
- 额外注意:你给出的文档示例中rating是字符串类型,但POJO定义为int类型,若实际存储为字符串,需先转为数值再计算平均值,否则
$avg会返回null
正确实现代码
1. 修正后的Repository定义
public interface RatingDao extends MongoRepository<Rating , String> { @Aggregation(pipeline = { "{$match: {userId: ?0}}", // 绑定方法第一个入参,先过滤指定userId的所有记录 "{$group: {_id: null, avgRating: {$avg: '$rating'}}}" // 对过滤后的记录计算平均评分 }) Optional<Double> calculateAverageRatingByUserId(String userId); }
2. 调用示例
可以根据业务需求处理无评分的空场景:
public double getUserAvgRating(String userId) { // 无对应评分记录时默认返回0.0,可根据需求调整默认值 return ratingDao.calculateAverageRatingByUserId(userId).orElse(0.0); }
3. 适配字符串存储rating的场景
如果你的数据库中rating实际存储为字符串类型,调整聚合逻辑做类型转换即可:
public interface RatingDao extends MongoRepository<Rating , String> { @Aggregation(pipeline = { "{$match: {userId: ?0}}", "{$group: {_id: null, avgRating: {$avg: {$toInt: '$rating'}}}}" }) Optional<Double> calculateAverageRatingByUserId(String userId); }
内容的提问来源于stack exchange,提问作者Sakura
相关产品推荐
相关产品推荐

