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

 更新时间:2022年06月30日 10:59:08   作者:intomylife  
这篇文章主要介绍了使用mongoTemplate实现多条件加分组查询方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教

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

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后面,否则结果集不准确。

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • Java9中新增的Collector收集器

    Java9中新增的Collector收集器

    这篇文章主要介绍了Java9中新增的Collector收集器,Collector作为收集器,简单来说就是将数据或元素收集到一起,并且flatMapping与收集器结合使用,通过提供智能元素集合进行分组。下文相关介绍需要的小伙伴可以参考一下
    2022-06-06
  • Java实现的打地鼠小游戏完整示例【附源码下载】

    Java实现的打地鼠小游戏完整示例【附源码下载】

    这篇文章主要介绍了Java实现的打地鼠小游戏,结合完整实例形式分析了Java多线程操作及键盘按键响应实现的打地鼠游戏功能相关操作技巧,需要的朋友可以参考下
    2018-07-07
  • 关于线程池你不得不知道的一些设置

    关于线程池你不得不知道的一些设置

    这篇文章主要介绍了关于线程池你不得不知道的一些设置,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧<BR>
    2019-04-04
  • java9版本特性资源自动关闭的语法增强

    java9版本特性资源自动关闭的语法增强

    这篇文章主要为大家介绍了java9版本特性资源自动关闭的语法增强的详细使用说明,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步
    2022-03-03
  • 里氏代换原则_动力节点Java学院整理

    里氏代换原则_动力节点Java学院整理

    这篇文章主要为大家详细介绍了里氏代换原则的相关资料,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-08-08
  • 详解Swagger接口文档和常用注解的使用

    详解Swagger接口文档和常用注解的使用

    Swagger是一款遵循 Restful 风格的接口文档开发神器,支持基于 API 自动生成接口文档。本文将为大家讲讲Swagger接口文档和常用注解的使用方法,需要的可以参考一下
    2022-08-08
  • Java设计模式之抽象工厂模式详解

    Java设计模式之抽象工厂模式详解

    这篇文章主要介绍了Java设计模式之抽象工厂模式详解,抽象工厂是一种为访问类提供一个创建一组相关或相互依赖对象的接口,且访问类无须指定所要产品的具体类就能得到同族的、不同等级的产品的模式结构,需要的朋友可以参考下
    2023-09-09
  • SpringBoot实现接口的各种参数校验的示例

    SpringBoot实现接口的各种参数校验的示例

    本文主要介绍了SpringBoot实现接口的各种参数校验的示例,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-01-01
  • Java Dubbo协议下的服务端线程使用详解

    Java Dubbo协议下的服务端线程使用详解

    Dubbo是阿里开源项目,国内很多互联网公司都在用,已经经过很多线上考验。Dubbo内部使用了Netty、Zookeeper,保证了高性能高可用性,使用Dubbo可以将核心业务抽取出来,作为独立的服务,逐渐形成稳定的服务中心
    2023-03-03
  • 说明Java的传递与回调机制的代码示例分享

    说明Java的传递与回调机制的代码示例分享

    这篇文章主要介绍了说明Java的传递与回调机制的代码示例分享,传递与回调机制是Java入门学习中的基础知识,需要的朋友可以参考下
    2015-09-09

最新评论