聚合框架不能使用索引

时间:2012-11-20 03:16:28

标签: mongodb indexing

我运行此命令:

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不使用索引。任何人都知道是否可以聚合框架使用索引,如何索引此查询。

3 个答案:

答案 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之前,聚合过程需要花费几秒钟的时间。