mongo-Aggregation聚合查询踩坑

本文通过一个具体的例子展示了在MongoDB中,聚合管道操作的顺序对查询结果的影响。原始代码由于将`.project()`操作置于`.match()`之前,导致查询返回空结果。原因是MongoDB的管道处理需从上到下传递,`.project()`中依赖的`sTime`字段在`.match()`之后才能被赋值。调整顺序后,查询正常返回数据。了解这种机制对于优化MongoDB查询至关重要。
摘要由CSDN通过智能技术生成

目的:

按天对数据进行分组

问题:

一开始的写法如下(简写,凸显问题),聚合查出的数据都为空,数量为零

String startTime = "2021-08-30 00:00:00";
String endTime = "2021-09-30 00:00:00";
Aggregation aggregation = Aggregation.newAggregation(
       Aggregation.project("sTime").andExpression("substr(sTime,0,10)").as("day"),
       Aggregation.match(Criteria.where("sId").is(1)
               .and("sTime").gte(startTime).lt(endTime)),
       Aggregation.group("day")
 );
AggregationResults<Map> results = mongoTemplate.aggregate(aggregation, MONGO_TABLE_NAME, Map.class);
results.getMappedResults().forEach(System.out::println);
List<Map> mapList = results.getMappedResults();
System.out.println("数量:"+mapList.size());

修改为如下代码解决:

String startTime = "2021-08-30 00:00:00";
String endTime = "2021-09-30 00:00:00";
Aggregation aggregation = Aggregation.newAggregation(
       Aggregation.match(Criteria.where("sId").is(1)
               .and("sTime").gte(startTime).lt(endTime)),
       //将.project() 放到 .match() 条件后
       Aggregation.project("sTime").andExpression("substr(sTime,0,10)").as("day"),
       Aggregation.group("day")
 );
AggregationResults<Map> results = mongoTemplate.aggregate(aggregation, MONGO_TABLE_NAME, Map.class);
results.getMappedResults().forEach(System.out::println);
List<Map> mapList = results.getMappedResults();
System.out.println("数量:"+mapList.size());

解释:

  • mongo没有像mysql一样存在子查询的概念
  • mongo有管道的概念,也可以把管道理解成mysql中子查询
  • Aggregation相当于一个管道,需要从上至下将处理结果传递下去,如果直接将project放到match前边后,project中需要的sTime参数将得不到赋值,通过打印的mongo语句可以看到sTime=1(这个应该是未知参数的默认值),所以导致每次查询都为空

其他:

打印mongo语句日志,配置文件中添加如下配置:

logging.level.org .springframework.data.mongodb.core= DEBUG

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值