• mongodb 聚合Aggregation分组group汇总索引问题


    项目中,需要对mongo中某个集合进行分组汇总,集合主要包含下面几个字段

    1. // 日期
    2. private Integer date;
    3. // 账号id
    4. private Long accountId;
    5. // 标题
    6. private String title;
    7. // 状态
    8. private Integer status;
    9. // 状态🐴
    10. private String statusCode;
    11. // 数量
    12. private Integer count;

    集合主要包含下面两个索引

    1. {
    2. "v" : 2,
    3. "key" : {
    4. "date" : -1.0,
    5. "accountId" : 1.0,
    6. "status" : 1.0
    7. },
    8. "name" : "date_-1_accountId_1_status_1",
    9. "background" : true
    10. },
    11. {
    12. "v" : 2,
    13. "key" : {
    14. "date" : -1.0,
    15. "accountId" : 1.0,
    16. "title" : 1.0
    17. },
    18. "name" : "date_-1_accountId_1_title_1",
    19. "background" : true
    20. },

    现在想对指定日期、指定账号下的数据不同标题下面的数量进行汇总,刚开始使用下面代码:

    1. Aggregation aggregation = Aggregation.newAggregation(
    2. Aggregation.match(Criteria.where("date")
    3. .is(date).and("accountId").is(accountId)),
    4. Aggregation.group("title", "statusCode")
    5. .sum("count").as("totalCount"));

    但是实际在测试的时候,发现速度比较慢(数据库千万级),通过查看mongo日志,发现走的是date_-1_accountId_1_status_1索引,并没有使用date_-1_accountId_1_title_1索引。

    于是查询mongo官方文档Aggregation Pipeline — MongoDB Manual,怎样才能使用group中的字段索引,发现了有如下说明:

    1. $group
    2. The $group stage can sometimes use an index to find the first document in each group if all of the following criteria are met:
    3. The $group stage is preceded by a $sort stage that sorts the field to group by,
    4. There is an index on the grouped field which matches the sort order and
    5. The only accumulator used in the $group stage is $first
    6. See Optimization to Return the First Document of Each Group for an example.

    具体意思大家自己翻译,我理解的意思是,将分组group的列进行排序一下,应用到我们这个场景,就是将title字段排序一下,就可能走date_-1_accountId_1_title_1索引,聚合速度可能就更快了。

    以上只是猜想,实践如下:

    1. Sort sort = new Sort(Sort.Direction.ASC, "title");
    2. Aggregation aggregation = Aggregation.newAggregation(
    3. Aggregation.match(Criteria.where("date")
    4. .is(date).and("accountId").is(accountId)),
    5. Aggregation.sort(sort),
    6. Aggregation.group("title").sum("count").as("totalCount")
    7. );

    测试结果,查看mongo日志,确实走了date_-1_accountId_1_title_1索引,聚合速度相对之前也快了不少。

    总结

    mongo很多知识点在网上搜到的都是比较基础,很多都是告诉你Aggregation聚合基本用法,一些复杂一点的用法,还是得自己去看官方文档比较靠谱,之前遇到的几个MongoDB问题,都是通过查看官方文档解决的,官方文档也比较详细。

  • 相关阅读:
    微信自动化推送天气预报信息教程【Python版源代码】
    大数据之LibrA数据库常见术语(七)
    手写call方法
    Django(三)接口自动化平台HttpRunnerManager(2)基本使用介绍
    网络安全专业术语中英对照指南
    5分钟安装Kubernetes+带你轻松安装istio服务网格指南
    Linux C 应用搜索动态库
    数据结构-栈的实现
    以深圳为例Python一键生成核酸检测日历
    零基础HTML教程(31)--HTML5多媒体
  • 原文地址:https://blog.csdn.net/maxi1234/article/details/127778663