首页 > 解决方案 > MongoDB 聚合查询(组)花费太多时间

问题描述

小组赛阶段需要 5 分钟才能执行,我的收藏中有 100000000 条记录。我正在使用 mongodb 4.2,我有 8 个 cpu 和 32gb RAM。有没有更好的方法来优化查询或索引?

db.getCollection("text").explain("executionStats").aggregate(
[
    { 
        "$match" : { 
            "CreatedDate" : { 
                "$gte" : ISODate("2021-01-01T15:43:50.325+0000"), 
                "$lte" : ISODate("2021-03-29T15:43:50.325+0000")
            }
        }
    }, 
    { 
        "$project" : { 
            "TX_DATE" : { 
                "$dateToString" : { 
                    "format" : "%Y-%m", 
                    "date" : "$CreatedDate"
                }
            }, 
            "Exp_Count" : 1.0
        }
    }, 
    { 
        "$group" : { 
            "_id" : { 
                "TX_DATE_Month" : "$TX_DATE"
            }, 
            "Exp_Count" : { 
                "$sum" : "$Exp_Count"
            }
        }
    }, 
    { 
        "$project" : { 
            "_id" : 0.0, 
            "TX_DATE" : "$_id.TX_DATE_Month", 
            "Exp_Count" : 1.0
        }
    }, 

    { 
        "$sort" : { 
            "TX_DATE" : 1.0
        }
    }
], 
{ 
    "allowDiskUse" : false
}

);

标签: mongodbmongodb-queryaggregation-framework

解决方案


$match阶段:可以帮助你,

匹配阶段仅用于选择所需的文件。这种匹配将减少我们对所需文档的聚合过程。它更类似于我们在 MySQL 查询中使用的 where 子句。匹配帮助我们使用我们在集合中创建的索引。通过在匹配阶段使用索引键,可以很容易地在集合中查找和分组所需的文档。例如,将学校数据中年龄为 13 岁的学生的数据按性别分组,并以年龄为索引。按性别聚合的命令:

db.SchoolData.aggregate([{’$match’:{’age’:13}},{’$group’:{’_id’:’$gender’}}])

这将减少我们对年龄为 13 的文档的关注,并且在同一键上建立索引,这将变得更加高效。

注意,

db.SchoolData.aggregate([{’$match’:{’age’:13}},{’$group’:{’_id’:’$gender’}}])

db.SchoolData.aggregate([{’$group’:{’_id’:’$gender’}},{’$match’:{’age’:13}}])

将具有完全不同的执行时间,因为在第一个命令中它仅对年龄为 13 的文档执行聚合,而在第二种情况下,它对所有文档进行聚合并返回年龄为 13 的结果。


推荐阅读