我是一个按行动记录条目的系统。其中超过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文档分组加入? 感谢
答案 0 :(得分:0)
要加快您的特定查询,您需要created_at
字段的索引。
但是,聚合的整体性能还取决于您的硬件规格(以及其他内容)。
如果您发现查询的效果低于您的要求,您可以:
如果您需要始终运行此聚合查询,则预先聚合的报告允许您使用简单的find()
查询获取可以访问的数据的最新聚合报告。< / p>
权衡是,对于每次插入,您还需要更新预先聚合的文档以反映数据的当前状态。但是,与必须运行可能干扰您日常操作的长/复杂聚合查询相比,这是一个相对较小的权衡。
聚合框架的一个警告是:一旦聚合管道遇到$group
或$project
阶段,就不能使用索引。这是因为MongoDB索引与物理存储文档的方式有关。分组和投影将文档转换为文档在磁盘中没有物理表示的状态。