Spring Boot中如何在Mongo CriteriaQuery里使用$dateToString
Spring Data MongoDB聚合查询中使用$dateToString按日期分组
我来帮你搞定这个问题!你用原生MongoDB聚合能按日期(不带时间)和IP分组统计,但Spring Data的代码却按完整的datetime字段分组,核心就是要在Spring Data的聚合操作里实现$dateToString的逻辑,具体可以这么做:
首先,你需要放弃直接用字段名"datetime"分组,而是通过自定义聚合表达式来生成格式化后的日期字符串,同时保留IP作为分组维度,和原生聚合逻辑对齐。Spring Data MongoDB提供了AggregationExpression接口来实现这类自定义MongoDB操作符的逻辑。
修改后的完整代码
// 保留原有的日期范围和用户ID过滤条件 Criteria criteria = Criteria.where("user._id").is(paramuserid) .and("datetime").gte(paramfirstdate) .and("datetime").lt(paramseconddate); AggregationOperation match = Aggregation.match(criteria); // 构建分组操作:按格式化后的日期 + IP分组,统计数量 AggregationOperation group = Aggregation.group( // 用AggregationExpression实现$dateToString逻辑,格式化日期为dd-MM-yyyy AggregationExpression.from(context -> new Document("$dateToString", new Document("format", "%d-%m-%Y") .append("date", "$datetime") ) ).as("datetime"), "$ip" // 同时按IP字段分组 ).count().as("count"); // 对应原生的$sum:1,统计每组的登录次数 List<AggregationOperation> aggregationOperations = new ArrayList<>(); aggregationOperations.add(match); aggregationOperations.add(group); // 建议创建DTO类接收结果,替代Object.class AggregationResults<LoginStats> aggregationResults = this.mngT.aggregate( Aggregation.newAggregation(aggregationOperations), Login.class, LoginStats.class );
补充说明
- 自定义聚合表达式:
AggregationExpression.from()用来构建原生MongoDB的$dateToString操作,和你原生语句里的逻辑完全一致,把datetime字段格式化为%d-%m-%Y的字符串作为分组键。 - 分组维度对齐:同时把
$ip加入分组条件,和原生聚合的分组逻辑保持一致,确保按「日期+IP」维度统计。 - 结果接收DTO:建议创建一个
LoginStats类来接收聚合结果,比用Object.class更清晰,示例如下:
public class LoginStats { private String datetime; private String ip; private long count; // 构造方法、getter和setter }
这样修改后,你的Spring Data聚合查询就会和原生语句的效果完全一致,按不带时间的日期和IP分组统计登录次数了。
内容的提问来源于stack exchange,提问作者Fatih Can
相关产品推荐
相关产品推荐

