我运行此命令:
db.ads_view.aggregate({$ group:{_ id:“$ campaign”,“action”:{$ sum:1}}});
ads_view:500 000个文件。
此查询需要1.8秒。这是它的个人资料:https://gist.github.com/afecec63a994f8f7fd8a
索引:db.ads_view.ensureIndex({campaign:1});
但是mongodb不使用索引。任何人都知道是否可以聚合框架使用索引,如何索引此查询。
答案 0 :(得分:6)
$group
运算符不是当前将使用索引的运算符之一。执行的操作符列表(从2.2开始)是:
$match
$sort
$limit
$skip
从这里开始:
http://docs.mongodb.org/manual/applications/aggregation/#pipeline-operators-and-indexes
根据要点中的收益数量,我会假设你有一个非常活跃的实例,或者当你做这个组时,很多这些数据不在内存中(通常会产生页面错误)因此,1.8s
请注意,即使$group
可以使用索引,并且您的索引涵盖了所有正在分组的内容,但仍然需要对索引进行完整扫描以执行该组,并且无论如何都可能不会很快。 / p>
答案 1 :(得分:0)
$group
不使用索引,因为它不需要。当您$group
项目时,您实际上是使用$group
的{{1}}索引通过管道$group
阶段的所有文档。如果您使用的索引与_id
的{{1}}匹配,那么您仍然必须通过索引中的所有文档,以便进行相同的工作量。
答案 2 :(得分:0)
这是一个较晚的答案,但是由于Mongo自版本4.0起的$group
仍不会使用索引,因此对其他人可能会有所帮助。
要显着加快聚合速度,请在$sort
之前执行$group
。
因此您的查询将变为:
db.ads_view.aggregate({$sort:{"campaign":1}},{$group: {_id : "$campaign", "action" : {$sum: 1} }});
这假定应该根据您的问题在campaign
上创建索引。在Mongo 4.0中,使用db.ads_view.createIndex({campaign:1})
创建索引。
我在包含5.5+ Mio的集合上对此进行了测试。文件。如果没有$sort
,则即使几个小时后聚合也不会完成; $sort
位于$group
之前,聚合过程需要花费几秒钟的时间。