MongoDB聚合按月按大集合分组-优化管道

问题描述 投票:0回答:1

我知道这个问题以前是在SO处提出的-但我似乎找不到如何处理较大集合中的聚合分组的方法。我有一组+1000万条记录,但是我无法无速前进。

正在运行MongoDB v 3.2。

在模式中具有字段__createDateUtc(ISODate),我正在尝试以下管道:

db.transactions.aggregate([
    {
        $project: {
            __createDateUtc: 1
        }
    },
    {
        $group: {
            '_id': { $year: '$__createDateUtc' },
            'count': {$sum: 1},
        }
    },
    {
        $limit: 10
    },
])

此时间为+20秒。可以更快吗?这是一个非常简单的管道-的确如此-在这种情况下是否还有其他策略可能会有所帮助?

mongodb
1个回答
0
投票

我用四种不同的方式进行基准测试,以获得所需的结果。结果令人沮丧。

再次,使用类似如下的模式:

{
    "_id" : ObjectId("5d665491fd5852755236a5dc"),
    ...
    "__createDateUtc" : ISODate("2019-08-28T10:16:49Z"),
    "__createDate" : {
        "year" : 2019,
        "month" : 8,
        "day" : 28,
        "yearMonth" : 201908,
        "yearMonthDay" : 20190829
    }
}

结果:

// Group by __createDate.yearMonth
db.transactions.aggregate([
    { $group: {
        '_id': '$__createDate.yearMonth',
        'count': {$sum: 1},
    } },
    { $limit: 10 },
    { $sort: {'_id': -1 } }
])
// 20 169 ms

// Group by year and month
db.transactions.aggregate([
    {$group: {
            '_id': {year: '$__createDate.year', month: '$__createDate.month' },
            'count': {$sum: 1},
    }},
    { $limit: 10 },
    { $sort: {'_id': -1 } }
])
// 23 777 ms

// Group by calculating year and month from ISODate
db.transactions.aggregate([
    {$group: {
            '_id': {year: { $year: '$__createDateUtc' }, month: { $month: '$__createDateUtc' } },
            'count': {$sum: 1},
    }},
    { $limit: 10 },
    { $sort: {'_id': -1 } }
])
// 16 444 ms

// Last stupid method to just run many queries with count
var years = [2017, 2018, 2019];
var results = {}
years.forEach(year => {
    results[year] = {};
    for(var i = 1; i < 13; i++) {
        var count = db.transactions.find({'__createDate.year': year, '__createDate.month': i}).count();
        if(count > 0) results[year][i] = count;
    }
})
// 10 701 ms

您可以看到,仅运行多个计数的最后一种方法是最快的。特别是因为与其他三种方法相比,我实际上正在获取更多数据。

这对我来说似乎很愚蠢。我知道MongoDB不是搜索引擎,但是仍然。聚合根本不是很快。让我想将数据同步到弹性搜索,并尝试在ES中进行汇总。

© www.soinside.com 2019 - 2024. All rights reserved.