【发布时间】:2022-01-21 16:46:51
【问题描述】:
我有以下聚合管道来计算嵌入评论的手机集合中评分最高的品牌。
public Document findTopRatedBrands(int minReviews, int results) {
UnwindOperation unwindOperation = unwind("reviews");
GroupOperation groupOperation = group("$brand").avg("$reviews.rating")
.as("avgRating").count().as("numReviews");
MatchOperation matchOperation = match(new Criteria("numReviews").gte(minReviews));
SortOperation sortOperation = sort(Sort.by(Sort.Direction.DESC, "avgRating",
"numReviews"));
LimitOperation limitOperation = limit(results);
ProjectionOperation projectionOperation = project().andExpression("_id").as
("brand").andExpression("avgRating").as("rating").andExclude("_id")
.andExpression("numReviews").as("reviews");
Aggregation aggregation = newAggregation(unwindOperation, groupOperation, matchOperation,
sortOperation, limitOperation, projectionOperation);
AggregationResults<Phone> result = mongoOperations
.aggregate(aggregation, "phones", Phone.class);
return result.getRawResults();
}
phones 集合中的文档示例如下:
{
"_id": {
"$oid": "61e1cc8f452d0aef89d9125f"
},
"brand": "Samsung",
"name": "Samsung Galaxy S7",
"releaseYear": 2016,
"reviews": [{
"_id": {
"$oid": "61d4403b86913bee0245c171"
},
"rating": 2,
"dateOfReview": {
"$date": "2019-12-24T00:00:00.000Z"
},
"title": "Won't do that again.",
"body": "I could not use with my carrier. Sent it back.",
"username": "bigrabbit324"
}]
}
我想按 avgRating(四舍五入到小数点后一位)排序,其次按评论数排序。现在平均评分它没有四舍五入,所以它总是给出不同的值,所以我也不能按评论数量排序。我已经看过 ArithmeticOperators.Round 类,但如果可能的话,我不明白如何在此处包含它。
结果示例如下:
[Document{{brand=Nokia, rating=3.25, reviews=4}}]
我希望评分为 3.2。
这适用于 Mongo Compass:
$project: {
_id: 0,
brand: '$_id',
rating: { $round: ['$avgRating', 1] }
}
【问题讨论】:
-
你能发布一些示例数据吗?
-
从新的示例数据中,听起来您正在尝试实现类似的目标:mongoplayground.net/p/tS_6iwCvlur 您的更新问题提到
$round在 mongo compass 中工作,但您在下面的评论中提到您遇到错误使用$round。您能否澄清一下您的环境是否支持$round,您的 mongodb 版本 >= 4.2
标签: spring mongodb mongodb-query aggregation-framework spring-data-mongodb