• 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问题,都是通过查看官方文档解决的,官方文档也比较详细。

  • 相关阅读:
    小程序排名第三-我又焦虑了
    mysql数据库中的插入数据insert,中文字符集配置
    Splunk macros 从理论到实践
    PMP考试多少分算通过?
    Git 工作流程
    OpenBox(一个高效通用的黑盒优化系统)安装与使用
    Hive 查询优化
    Sylar C++高性能服务器学习记录05 【线程模块-知识储备篇】
    振动监测:物联网预测性维护的“听诊器”
    Microsoft SQL Server中的错误配置
  • 原文地址:https://blog.csdn.net/maxi1234/article/details/127778663