项目中,需要对mongo中某个集合进行分组汇总,集合主要包含下面几个字段
- // 日期
- private Integer date;
-
- // 账号id
- private Long accountId;
-
- // 标题
- private String title;
-
- // 状态
- private Integer status;
-
- // 状态🐴
- private String statusCode;
-
- // 数量
- private Integer count;
集合主要包含下面两个索引
- {
- "v" : 2,
- "key" : {
- "date" : -1.0,
- "accountId" : 1.0,
- "status" : 1.0
- },
- "name" : "date_-1_accountId_1_status_1",
- "background" : true
- },
-
- {
- "v" : 2,
- "key" : {
- "date" : -1.0,
- "accountId" : 1.0,
- "title" : 1.0
- },
- "name" : "date_-1_accountId_1_title_1",
- "background" : true
- },
现在想对指定日期、指定账号下的数据不同标题下面的数量进行汇总,刚开始使用下面代码:
- Aggregation aggregation = Aggregation.newAggregation(
- Aggregation.match(Criteria.where("date")
- .is(date).and("accountId").is(accountId)),
- Aggregation.group("title", "statusCode")
- .sum("count").as("totalCount"));
但是实际在测试的时候,发现速度比较慢(数据库千万级),通过查看mongo日志,发现走的是date_-1_accountId_1_status_1索引,并没有使用date_-1_accountId_1_title_1索引。
于是查询mongo官方文档Aggregation Pipeline — MongoDB Manual,怎样才能使用group中的字段索引,发现了有如下说明:
- $group
- The $group stage can sometimes use an index to find the first document in each group if all of the following criteria are met:
-
- The $group stage is preceded by a $sort stage that sorts the field to group by,
-
- There is an index on the grouped field which matches the sort order and
-
- The only accumulator used in the $group stage is $first
-
- See Optimization to Return the First Document of Each Group for an example.
具体意思大家自己翻译,我理解的意思是,将分组group的列进行排序一下,应用到我们这个场景,就是将title字段排序一下,就可能走date_-1_accountId_1_title_1索引,聚合速度可能就更快了。
以上只是猜想,实践如下:
- Sort sort = new Sort(Sort.Direction.ASC, "title");
-
- Aggregation aggregation = Aggregation.newAggregation(
- Aggregation.match(Criteria.where("date")
- .is(date).and("accountId").is(accountId)),
- Aggregation.sort(sort),
- Aggregation.group("title").sum("count").as("totalCount")
- );
测试结果,查看mongo日志,确实走了date_-1_accountId_1_title_1索引,聚合速度相对之前也快了不少。
mongo很多知识点在网上搜到的都是比较基础,很多都是告诉你Aggregation聚合基本用法,一些复杂一点的用法,还是得自己去看官方文档比较靠谱,之前遇到的几个MongoDB问题,都是通过查看官方文档解决的,官方文档也比较详细。