是否可以使用 Spring 数据 MongoDB 聚合对数字进行舍入?
Is it possible to round a number with Spring data MongoDB aggregations?
我有以下聚合管道,用于从嵌入评论的一组手机中计算评分最高的品牌。
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 class 但我不明白如何尽可能将它包含在这里。
结果示例如下:
[Document{{brand=Nokia, rating=3.25, reviews=4}}]
我希望评分为 3.2。
这适用于 Mongo 指南针:
$project: {
_id: 0,
brand: '$_id',
rating: { $round: ['$avgRating', 1] }
}
尝试
ProjectionOperation roundAverageRating = Aggregation.project("avgRating", "numReviews")
.and(ArithmeticOperators.Round.roundValueOf("avgRating").place(1))
.as("avgRatingRounded");
我有以下聚合管道,用于从嵌入评论的一组手机中计算评分最高的品牌。
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 class 但我不明白如何尽可能将它包含在这里。
结果示例如下:
[Document{{brand=Nokia, rating=3.25, reviews=4}}]
我希望评分为 3.2。
这适用于 Mongo 指南针:
$project: {
_id: 0,
brand: '$_id',
rating: { $round: ['$avgRating', 1] }
}
尝试
ProjectionOperation roundAverageRating = Aggregation.project("avgRating", "numReviews")
.and(ArithmeticOperators.Round.roundValueOf("avgRating").place(1))
.as("avgRatingRounded");