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

目录
  • mongoTemplate实现多条件查询
  • 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后面,否则结果集不准确。

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

(0)

相关推荐

  • JAVA mongodb 聚合几种查询方式详解

    一.BasicDBObject 整个聚合查询是统计用户的各种状态下的用户数量为场景: 1.筛选条件: date为查询日期: BasicDBObject Query = new BasicDBObject(); Query.put("time",new BasicDBObject("$gte", date + " 00:00:00") .append("$lte", date + " 23:59:59"));

  • JAVA代码实现MongoDB动态条件之分页查询

    一.使用QueryByExampleExecutor 1. 继承MongoRepository public interface StudentRepository extends MongoRepository<Student, String> { } 2. 代码实现 使用ExampleMatcher匹配器-----只支持字符串的模糊查询,其他类型是完全匹配 Example封装实体类和匹配器 使用QueryByExampleExecutor接口中的findAll方法 public Page&

  • Java操作mongodb的模糊查询和精确查询

    本意是想查查mongo数据库的int类型的like怎么查,但是好像没 解决这个问题. 精确查询:模糊查询:分页查询,每页多少:按某个字段排序(或升或降):查询数量:大于,小于,等于:且,或,某个字段不为空,某个字段不存在,查询在某个范围内,删除等等查询. 一. 常用查询: 1. 查询一条数据:(多用于保存时判断db中是否已有当前数据,这里 is  精确匹配,模糊匹配 使用regex...) public PageUrl getByUrl(String url) { return findOne(

  • springboot+mongodb 实现按日期分组分页查询功能

    具体代码如下所示: WalletDetailsResp walletDetailsResp = new WalletDetailsResp(); List<WalletDetailsResp.WalletDetail> list = new ArrayList<>(); WalletDetailsResp.PageInfoBean pageInfoBean = new WalletDetailsResp.PageInfoBean(); List<Integer> typ

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

    目录 mongoTemplate实现多条件查询 mongoTemplate分组查询的坑 先来一个常见的错误信息: Due to limitations of the com.mongodb.BasicDocument, you can't add a second '$and' expression specified as '$and : 错误原因: 在一个 Criteria 对象中调用了多次 andOperator() 方法 mongoTemplate实现多条件查询 多个条件的查询只需要创建

  • MySql中流程控制函数/统计函数/分组查询用法解析

    路漫漫其修远兮,吾将上下而求索,又到了周末,我继续带各位看官学习回顾Mysql知识. 上次说到了流程控制函数,那就从流程控制函数来继续学习吧! #五.流程控制函数 #1.if函数:if else的效果 IF(条件表达式,成立返回1,不成立返回2) #与Java三元运算相同 SELECT IF(10>5,'大','小'); SELECT last_name,commission_pct,IF(commission_pct IS NULL,'没奖金呵呵','有奖金嘻嘻') AS 备注 FROM em

  • Python模型聚合查询\Q查询\F查询\分组查询操作技巧解析

    目录 模型中的一些查询操作: 1.聚合查询:aggregate()是QuerySet 的一个终止子句 2.Q查询: 如果你需要执行更复杂的查询(例如OR语句) 3.F查询: (查询的是一整列数据!) 4.分组查询 4.1一对多关系 4.2多对多关系 模型中的一些查询操作: 1.聚合查询:aggregate()是QuerySet 的一个终止子句 它返回一个包含一些键值对的字典 from movie.models import User from django.db.models import Co

  • 详解MySQL中的分组查询与连接查询语句

    分组查询 group by group by 属性名 [having 条件表达式][ with rollup] "属性名 "指按照该字段值进行分组:"having 条件表达式 "用来限制分组后的显示,满足条件的结果将被显示:with rollup 将会在所有记录的最后加上一条记录,该记录是上面所有记录的总和. 1)单独使用 group by 单独使用,查询结果只显示一个分组的一条记录. 实例: select * from employee group by sex;

  • Oracle中分组查询group by用法规则详解

    Oracle中group by用法 在select 语句中可以使用group by 子句将行划分成较小的组,一旦使用分组后select操作的对象变为各个分组后的数据,使用聚组函数返回的是每一个组的汇总信息. 使用having子句 限制返回的结果集.group by 子句可以将查询结果分组,并返回行的汇总信息Oracle 按照group by 子句中指定的表达式的值分组查询结果. 在带有group by 子句的查询语句中,在select 列表中指定的列要么是group by 子句中指定的列,要么包

  • MySQL 分组查询和聚合函数

    概述 相信我们经常会遇到这样的场景:想要了解双十一天猫购买化妆品的人员中平均消费额度是多少(这可能有利于对商品价格区间的定位):或者不同年龄段的化妆品消费占比是多少(这可能有助于对商品备货量的预估). 这个时候就要用到分组查询,分组查询的目的是为了把数据分成多个逻辑组(购买化妆品的人员是一个组,不同年龄段购买化妆品的人员也是组),并对每个组进行聚合计算的过程:. 分组查询的语法格式如下: select cname, group_fun,... from tname [where conditio

  • MySQL 子查询和分组查询

    概述 子查询是SQL查询中的重要一块,是我们基于多表之间进行数据聚合和判断的一种手段,使得我们的处理复杂数据更加的便捷,这一节我们主要来了解一下子查询. 先做一下数据准备,这边建立三张表:班级.学生.毕业成绩表,用于后面的操作: drop database if exists `Helenlyn_Class`; create database `Helenlyn_Class`; /*班级表*/ DROP TABLE IF EXISTS `classes`; CREATE TABLE `class

  • MySQL数据库分组查询group by语句详解

    一:分组函数的语句顺序 1 SELECT ... 2 FROM ... 3 WHERE ... 4 GROUP BY ... 5 HAVING ... 6 ORDER BY ... 二:WHERE和HAVING筛选条件的区别 数据源 位置 关键字 WHERE 原始表 ORDER BY语句之前 WHERE HAVING 分组后的结果集 ORDER BY语句之后 HAVING 三:举例说明 #1.查询每个班学生的最大年龄 SELECT MAX(age),class FROM STU_CLASS GR

  • MySQL必备基础之分组函数 聚合函数 分组查询详解

    目录 一.简单使用 二.搭配DISTINCT去重 三.COUNT()详细介绍 四.分组查询 一.简单使用 SUM:求和(一般用于处理数值型) AVG:平均(一般用于处理数值型) MAX:最大(也可以用于处理字符串和日期) MIN:最小(也可以用于处理字符串和日期) COUNT:数量(统计非空值的数据个数) 以上分组函数都忽略空NULL值的数据 SELECT SUM(salary) AS 和,AVG(salary) AS 平均,MAX(salary) AS 最大,MIN(salary) AS 最小

随机推荐