一、Aggregation.group分组汇总
1.1 初始化数据
mongoTemplate.save(new Role("zhang1",5));
mongoTemplate.save(new Role("zhang2",6));
mongoTemplate.save(new Role("zhang3",12));
mongoTemplate.save(new Role("zhang4",14));
mongoTemplate.save(new Role("zhang5",23));
mongoTemplate.save(new Role("zhang1",6));
mongoTemplate.save(new Role("zhang5",24));
1.2 分组查询
TypedAggregation<Role> agg = Aggregation.newAggregation(Role.class,
Aggregation.group("name").
sum("age").as("agesum").
first("age").as("agefirst").
addToSet("age").as("agess")
);
AggregationResults<Document> result = mongoTemplate.aggregate(agg,Document.class);
result.getMappedResults().forEach(document -> System.out.println(document));
1.3 结果
Document{{_id=zhang1, agesum=11, agefirst=5, agess=[6, 5]}}
Document{{_id=zhang2, agesum=6, agefirst=6, agess=[6]}}
Document{{_id=zhang3, agesum=12, agefirst=12, agess=[12]}}
Document{{_id=zhang5, agesum=47, agefirst=23, agess=[24, 23]}}
Document{{_id=zhang4, agesum=14, agefirst=14, agess=[14]}}
1.4 函数说明
-
$sum
:对每个group指定字段值进行累加计算。忽略非数字的值。 -
$avg
:对每个group进行“平均值”,忽略非数字的值。 -
$first
:返回每个group的第一条数据,顺序由$sort决定,如果没有排序,默认为文档的自然存储顺序。 -
$last
:返回每个group的最后一条数据,顺序由$sort决定,如果没有排序,默认为文档的自然存储顺序。 -
$max
、$min
:获取每个group中最大、最小值。 -
$push
:将指定的表达式的值添加到一个数组中,注意最终返回的document尺寸不要超过16M。 -
$addToSet
:将表达式的值添加到一个集合中(无重复值),注意最终分那会的document尺寸不要超过16M。
二、Aggregation.group分组复杂查询
2.1 实体类
2.1.1 动态实体
@Data
public class DynamicDetailEntity{
//动态内容
private String content;
//缩略图
private String thumbnail;
//动态日历
@Field(value = "calendar")
private CalendarDetail calendar;
//其他字段省略
}
2.1.2 动态日历实体
@Data
public class CalendarDetail {
//主题(话题)
private String title;
//日历类型
@Field(value = "calendar_type")
private Integer calendarType = 0;
//动态发布在哪天日期列表
@Field("activity_dates")
private List<CalendarEventTime> activityDates;
}
2.2.3 发布日历实体
@Data
@Builder
public class CalendarEventTime {
//日期时间戳
private Long localDateTimestamp;
//点赞次数
@Field(value = "like_nums")
private Long likeNums = 0l;
}
2.2 实现功能要点
1、分组去重(group)
2、List对象展开查询(unwind)
3、按List里对象的某个字段查询(calendar.activity_dates.localDateTimestamp)
2.3 查询实现
public List<String> listCalendarTypeTitle(Integer calendarType, String date) {
List<AggregationOperation> operations = new ArrayList<>();
operations.add(MongoUtils.match("deleted", false));
operations.add(MongoUtils.match("calendar.calendar_type", calendarType));
//将List展开
operations.add(Aggregation.unwind("calendar.activity_dates"));
try {
//查当天内的
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
LocalDate startTimeDate = LocalDate.parse(date, formatter);
LocalDate endTimeDate = startTimeDate.plusDays(1);
operations.add(Aggregation.match(Criteria.where("calendar.activity_dates").exists(true)
.andOperator(Criteria.where("calendar.activity_dates.localDateTimestamp").gte(startTimeDate.atStartOfDay().toInstant(ZoneOffset.of("+8")).toEpochMilli()),
Criteria.where("calendar.activity_dates.localDateTimestamp").lt(endTimeDate.atStartOfDay().toInstant(ZoneOffset.of("+8")).toEpochMilli()))));
} catch (Exception e) {
log.error(e.getMessage());
}
//分组(去重) 使用mongoTemplate.findDistinct去重,不支持排序
operations.add(Aggregation.group("calendar.title").first("calendar.title").as("title"));
Aggregation aggregation = Aggregation.newAggregation(operations);
AggregationResults<CalendarTitleVO> results = mongoTemplate.aggregate(aggregation, new DynamicDetailEntity().getTableName(), CalendarTitleVO.class);
List<CalendarTitleVO> record = results.getMappedResults();
List<String> calendarTypeTitleList = new ArrayList<>();
for (CalendarTitleVO calendar : record) {
if (StringUtil.isNotEmpty(calendar.getTitle())) {
calendarTypeTitleList.add(calendar.getTitle());
}
}
return calendarTypeTitleList;
}
网友评论