如何在Spring Data Mongo聚合group阶段使用$dayOfYear等DateOperators
解决方案
Spring Data MongoDB 内置的DateOperators工具类已经封装了所有MongoDB原生日期运算符,你可以直接将构造好的日期运算表达式传入分组字段的定义中,不需要手动拼接原生JSON语句。
固定字段分组写法
如果你分组的字段是固定的,直接链式调用GroupOperation的and方法传入表达式即可,代码如下:
import org.springframework.data.mongodb.core.aggregation.DateOperators; // 原有匹配阶段逻辑保持不变 MatchOperation matchStage = ... // 构造分组阶段 GroupOperation groupStage = Aggregation.group() // 添加普通分组字段 .and("city").as("city") // 传入日期运算表达式,指定别名作为分组键 .and(DateOperators.DayOfYear.dayOfYear("date")).as("dayOfYear") // 配置聚合指标,对应原生语句的$sum .sum("profit").as("totalProfit"); // 管道组装逻辑和原有一致 List<AggregationOperation> aggStages = new ArrayList<>(); aggStages.add(matchStage); aggStages.add(groupStage); Aggregation aggregation = Aggregation.newAggregation(aggStages);
动态拼接分组字段写法
如果你需要和原有代码一样动态拼接分组字段,就可以用Fields.field的重载方法,将日期运算表达式作为目标值传入Fields对象:
import org.springframework.data.mongodb.core.aggregation.DateOperators; Fields groupingFields = Fields.fields(); // 原有普通字段添加逻辑不变 groupingFields = groupingFields.and(name1, target1); groupingFields = groupingFields.and(name2, target2); // 添加日期运算类型的分组字段 groupingFields = groupingFields.and( Fields.field("dayOfYear", DateOperators.DayOfYear.dayOfYear("date")) ); GroupOperation groupStage = Aggregation.group(groupingFields) .sum("profit").as("totalProfit");
其他日期维度分组用法
如果需要按其他日期维度分组,替换对应的DateOperators实现即可:
- 按年份分组:
DateOperators.Year.year("date") - 按月份分组:
DateOperators.Month.month("date") - 按周几分组:
DateOperators.DayOfWeek.dayOfWeek("date") - 按小时分组:
DateOperators.Hour.hour("date")
如果需要指定时区计算,Spring Data MongoDB 2.2及以上版本支持给日期运算符配置时区:
// 按东八区时间计算年积日 DateOperators.DayOfYear.dayOfYear("date").withTimezone(TimeZone.of("Asia/Shanghai"))
内容的提问来源于stack exchange,提问作者racerX
相关产品推荐
相关产品推荐

