MongoDB聚合120M文档

时间:2016-08-07 16:41:42

标签: mongodb aggregation-framework

我是一个按行动记录条目的系统。其中超过120M,我想通过id_entry对它们进行分组。结构如下:

entry
{
    id_entry: ObjectId(...),
    created_at: Date(...),
    action: {object},
}

当我尝试通过id_entry进行聚合并对其操作进行分组时,需要3个多小时才能完成:

db.entry.aggregate([
{ '$match': {'created_at': { $gte:ISODate("2016-02-02"), $lt:ISODate("2016-02-03")}}},
{ '$group': {
    '_id' :{'id_entry': '$id_entry'},
    actions: {
        $push: '$action'
    }
}}])

但在那段时间里,只有约400万份文件。 (id_entry和created_at有索引)

我在总体上做错了什么?如何在不到3小时内通过id_entry将3-4M文档分组加入? 感谢

1 个答案:

答案 0 :(得分:0)

要加快您的特定查询,您需要created_at字段的索引。

但是,聚合的整体性能还取决于您的硬件规格(以及其他内容)。

如果您发现查询的效果低于您的要求,您可以:

  • 创建pre-aggregated report(本质上是一个包含所需汇总数据的文档,每次插入新数据时都会更新)或
  • 利用sharding将您的数据传播到更多服务器。

如果您需要始终运行此聚合查询,则预先聚合的报告允许您使用简单的find()查询获取可以访问的数据的最新聚合报告。< / p>

权衡是,对于每次插入,您还需要更新预先聚合的文档以反映数据的当前状态。但是,与必须运行可能干扰您日常操作的长/复杂聚合查询相比,这是一个相对较小的权衡。

聚合框架的一个警告是:一旦聚合管道遇到$group$project阶段,就不能使用索引。这是因为MongoDB索引与物理存储文档的方式有关。分组和投影将文档转换为文档在磁盘中没有物理表示的状态。