【问题标题】:Is it possible to round a number with Spring data MongoDB aggregations?是否可以使用 Spring 数据 MongoDB 聚合对数字进行舍入?
【发布时间】: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


【解决方案1】:

试试

ProjectionOperation roundAverageRating = Aggregation.project("avgRating", "numReviews")
    .and(ArithmeticOperators.Round.roundValueOf("avgRating").place(1))
    .as("avgRatingRounded");

【讨论】:

  • 我试过这个但给了我以下错误:org.springframework.data.mongodb.UncategorizedMongoDbException:命令失败,错误15999:'异常:服务器localhost上的无效运算符'$round''
  • new in mongodb version 4.2 中看起来像 $round。你运行的是什么版本的 mongodb?
  • 谢谢,我使用的是旧版本的单元测试 (3.0.1),它适用于 MongoDB 5.0.5
  • 很高兴它正在工作
猜你喜欢
  • 2017-04-23
  • 2018-10-28
  • 2017-06-02
  • 1970-01-01
  • 2017-01-06
  • 2017-07-14
  • 1970-01-01
  • 2022-06-24
  • 2018-02-05
相关资源
最近更新 更多