MongoDB之通过mongoTemplate利用aggregate管道聚合操作获取某一个或多个字段的最大值和最小值

1、问题场景

有时候在操作mongodb数据库时需要找出某个字段的最大值和最小值,网上的方法就两种,一种是先排序,按升序或者按降序,然后取第一个值就可以得到最大值或最小值了,听起来很美好,但一旦数据库内数据非常多的时候,而且还是mongoDB这样的数据库,如果查一遍库才能拿到值,代价是非常大的。所以我主要采用第二种方法,也就是利用mongodbTemplate来进行管道操作来获取mongodb数据库中某一个或多个字段的最大值和最小值。

2、具体方法(管道聚合操作)

public List<Integer> findMaxFoodAndMinFood() {
        // 排除数据为空或者为Null的情况
        Criteria criteria = Criteria.where("food").ne(null).andOperator(Criteria.where("food").ne(""));
        //  开始管道聚合操作
        Aggregation aggregation =  Aggregation.newAggregation(
                        // 先执行筛选
                        Aggregation.match(criteria),
                        // 按照id来分组(对应数据库里的id)
                        Aggregation.group("id")
                        // 找出food这个字段(对应数据库里的food)的最大值和最小值,并取个别名minFood和maxFood
                        .min("food").as("minFood")
                        .max("food").as("maxFood")
                        );
        // 分别放入aggregation和 数据库里的集合名“food_t”,BasicDBObject类
        AggregationResults<BasicDBObject> outputTypeCount = mongoTemplate.aggregate(aggregation, "food_t", BasicDBObject.class);
        // 定义一个 DBObject对象
        DBObject obj = new BasicDBObject();
        //  循环赋值
        for (Iterator<BasicDBObject> iterator = outputTypeCount.iterator(); iterator.hasNext(); ) {
            obj = iterator.next();
        }
        // 获取别名为maxFood的值(也就是最大值)
        Integer maxFood = (Integer) obj.get("maxFood");
        // 获取别名为minFood的值(也就是最小值)
        Integer minFood = (Integer) obj.get("minFood");
        // 添加到List集合
        List<Integer> foodList = new ArrayList<>();
        foodList.add(minFood);
        foodList.add(maxFood);
        // 这样最大值和最小值都找到了,而且还能取值,并存到foodList集合里
        return foodList;
    }

根据以上步骤自己慢慢来,就可以了。

3、结语

由于网上在这方面的代码比较少,所以我写一篇开源文档帮助这方面需要的人。其它的比如求和、求均值或者模糊查询,网上都有,而且很全,我就不献丑了。
最后,因为保密原因,我删减了很多,如果遇到问题,欢迎评论区留言,我都会解答的。

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 4
    评论
### 回答1: 在 MongoTemplate 中使用 distinct() 方法可以对某一字段进行去重。例如: ``` List<String> distinctAuthors = mongoTemplate.getCollection("book").distinct("author"); ``` 此外,也可以在查询中使用 group by 进行去重。例如: ``` Aggregation aggregation = newAggregation( group("author").first("author").as("author") ); AggregationResults<Author> results = mongoTemplate.aggregate(aggregation, "book", Author.class); List<Author> distinctAuthors = results.getMappedResults(); ``` 其中 "author" 是需要去重的字段名称。 ### 回答2: 在使用MongoTemplate进行查询时,如果需要对某一个字段进行去重,可以使用MongoDB聚合操作来实现。具体步骤如下: 1. 创建Aggregation操作对象: Aggregation agg = Aggregation.newAggregation( Aggregation.group("fieldName") // 根据需要去重的字段进行分组 ); 2. 执行聚合操作: AggregationResults<Document> results = mongoTemplate.aggregate(agg, "collectionName", Document.class); 3. 获取去重后的结果: List<Document> distinctList = results.getMappedResults(); 在上述代码中,"fieldName"需要替换为你要去重的字段名,"collectionName"需要替换为你要查询的集合名称。 执行聚合操作后,会将指定字段相同的文档进行分组,然后从分组结果中获取去重后的结果。最后将结果存储在List<Document>类型的distinctList中。 需要注意的是,使用聚合操作进行去重可能会有性能上的损耗,尤其是在大数据量的情况下。因此,建议在应用程序层面对数据进行去重,或者在数据写入MongoDB时进行去重处理,以提高查询性能。 ### 回答3: 在使用mongoTemplate进行查询时,对某一个字段进行去重可以通过MongoDB聚合管道操作实现。 首先,我们可以使用Aggregation类创建一个聚合管道操作的对象。然后,通过它的多个方法来定义聚合操作的各个阶段。在进行字段去重时,我们可以利用$group操作符进行分组,并在$group的_id字段中指定要去重的字段。接着,使用$push操作符将每个分组的字段值作为一个数组存储起来。最后,使用$project操作符将数组中的字段值重新赋值给目标字段。 具体实现代码如下所示: ``` Aggregation aggregation = Aggregation.newAggregation( Aggregation.group("$targetField").push("$targetField").as("fieldArray"), Aggregation.project("fieldArray").andExclude("_id") ); AggregationResults<YourEntity> results = mongoTemplate.aggregate( aggregation, "yourCollectionName", YourEntity.class ); List<YourEntity> distinctResults = results.getMappedResults(); ``` 在上述代码中,首先通过group方法指定要去重的字段作为分组依据,并将目标字段值存储在名为fieldArray的数组中。然后,使用project方法将数组中的字段值重新赋值给目标字段。最后,在调用aggregate方法执行聚合管道操作时,指定目标实体类的类型和集合名称。 最后,聚合操作的结果保存在results对象中,我们可以通过调用getMappedResults方法获取去重后的结果列表。 希望以上回答能够对你有所帮助!
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

熊凯瑞

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值