使用mongoTemplate实现多条件加分组查询方式

作者:intomylife 时间:2022-05-21 01:41:51 

先来一个常见的错误信息:

Due to limitations of the com.mongodb.BasicDocument, you can't add a second '$and' expression specified as '$and : 

错误原因:

在一个 Criteria 对象中调用了多次 andOperator() 方法

mongoTemplate实现多条件查询

多个条件的查询只需要创建 Query 对象,然后把需要添加的条件使用 Query 对象的 addCriteria() 方法

// 场景:查询指定时间段内,状态为1的数据
// 入参条件 :beginTime ,endTime ,statue
// mongodb字段:time , state

// 存放条件的对象
Query condition= new Query();

// 判断时间是否为空
if(beginTime != null && endTime != null){
   // 添加大于开始时间小于结束时间的条件
   condition.addCriteria(Criteria.where("time").gte(beginTime).lte(endTime));
}else{
   // 其中一个为空 分别进行判断
   if(beginTime != null){
       condition.addCriteria(Criteria.where("time").gte(beginTime));
   }
   if(endTime != null){
       condition.addCriteria(Criteria.where("time").lte(endTime));
   }
}

// 添加状态为1条件
if(statue!=null){
   condition.addCriteria(Criteria.where("state").is(statue));
}

条件有了后再调用 mongoTemplate.find(condition,返回类型.class,collectionName)

但是...想要分组,得调用 mongoTemplate.group(Criteria criteria , String inputCollectionName , GroupBy groupBy , Class<T> entityClass) 方法 (不是说只能这样才能分组,而是我通过这种方法实现了分组查询)

朋友们,第一个参数条件只能入参 Criteria 对象,而不能入参 Query 对象

结果我发现 Criteria 对象有 andOperator(Criteria ... criteria) 方法

这个方法就厉害了,可以入参数组,也就是说

我们可以把查询条件先存放到一个集合里面(因为数组需要定义长度,如果条件个数不确定,就不能直接定义数组),然后把集合放入数组中,再把数组入参 andOperator(Criteria ... criteria) 方法

// 场景:查询指定时间段内,状态为1的数据
// 入参条件 :beginTime ,endTime ,statue
// mongodb字段:time , state

// 定义一个存放条件的集合
List<Criteria> criteriaList = new ArrayList<>();
// 定义一个存放条件的数组(暂时不给长度)
Criteria[] criteriaArray = {};

// 判断时间是否为空
if(beginTime != null && endTime != null){
   // 添加大于开始时间小于结束时间的条件
   Criteria between = Criteria.where("time").gte(beginTime).lte(endTime);
   criteriaList.add(between);
}else{
   // 其中一个为空 分别进行判断
   if(beginTime != null){
       Criteria gte = Criteria.where("time").gte(beginTime);
       criteriaList.add(gte);
   }
   if(endTime != null){
       Criteria lte = Criteria.where("time").lte(endTime);
       criteriaList.add(lte);
   }
}

// 添加状态为1条件
if(statue!=null){
   Criteria isState = Criteria.where("state").is(statue);
   criteriaList.add(isState);
}

// 如果有条件
if(criteriaList.size()>0){
 // 集合的个数就是数组的长度
 criteriaArray = new Criteria[criteriaList.size()];
 // 遍历添加到数组中
 for(int i = 0 ; i<criteriaList.size(); i++){
     criteriaArray[i] = criteriaList.get(i);
  }
}

这种就可以调用 mongoTemplate.group(Criteria criteria , String inputCollectionName , GroupBy groupBy , Class<T> entityClass) 方法进行分组查询了

GroupBy groupBy = new GroupBy("分组字段")
                   .initialDocument("{ count: 0 }")
                   .reduceFunction("function (doc,pre){pre.count +=1 ;}");

// new Criteria().andOperator(criteriaArray) 这个是很关键的一步操作,把刚刚的条件数组放入进入
// groupByResults 这个对象里面内容很多,有兴趣的朋友可以断点进入看一下
GroupByResults groupByResults = mongoTemplate.
                   group(new Criteria().andOperator(criteriaArray), mongodb的collectionName, groupBy, 实体类.class);
// 获取分组后的数量
long resultCount = ((List)groupByResults.getRawResults().get("retval")).size();

mongoTemplate分组查询的坑

Aggregation agg = Aggregation.newAggregation(
                Aggregation.match(new Criteria().orOperator(new Criteria("to").is(ukey), new Criteria().and("fromAccount").is(ukey))),
                Aggregation.sort(Sort.Direction.DESC,"_id"),
                Aggregation.group("to","fromAccount")
        );

Aggregation.group 要排在Aggregation.match后面,否则结果集不准确。

来源:https://blog.csdn.net/qq_41402200/article/details/84651977

标签:mongoTemplate,多条件,分组,查询
0
投稿

猜你喜欢

  • java实现哈弗曼编码与反编码实例分享(哈弗曼算法)

    2023-11-25 04:54:05
  • Spring Cloud项目前后端分离跨域的操作

    2022-05-20 08:11:16
  • 使用注解解决ShardingJdbc不支持复杂SQL方法

    2022-08-03 02:15:12
  • Android Rxjava3 使用场景详解

    2023-08-06 08:58:50
  • java.lang.Runtime.exec的左膀右臂:流输入和流读取详解

    2023-08-06 04:59:03
  • 详解使用Maven开发Web应用详细步骤

    2023-08-06 14:18:20
  • opencv 做人脸识别 opencv 人脸匹配分析

    2023-07-09 06:34:44
  • Spring Cache+Redis缓存数据的实现示例

    2023-11-26 11:53:20
  • Mybatis-Plus进阶分页与乐观锁插件及通用枚举和多数据源详解

    2023-11-23 11:00:58
  • java操作Apache druid的实例代码

    2023-12-24 02:10:58
  • Java实现简单员工管理系统

    2021-12-13 17:51:26
  • Java中StringUtils与CollectionUtils和ObjectUtil概念讲解

    2023-11-29 07:45:38
  • JAVA 字符串加密、密码加密实现方法

    2023-11-28 04:08:09
  • java内存优化的方法总结

    2022-12-01 22:25:20
  • Kotlin与Java相互调用的完整实例

    2023-06-17 03:23:23
  • Java内存区域和内存模型讲解

    2023-11-26 12:08:39
  • Java按时间梯度实现异步回调接口的方法

    2023-11-09 10:30:29
  • Java修饰符 abstract,static,final 的区别详解

    2023-12-19 22:11:25
  • C# GDI+实现时钟表盘

    2023-06-20 07:11:32
  • 浅谈maven的jar包和war包区别 以及打包方法

    2022-07-20 20:14:44
  • asp之家 软件编程 m.aspxhome.com