6

我运行这个命令:

db.ads_view.aggregate({$group: {_id : "$campaign", "action" : {$sum: 1} }});

ads_view :500 000 个文档。

这个查询需要 1.8s 。这是它的简介:https ://gist.github.com/afecec63a994f8f7fd8a

索引:db.ads_view.ensureIndex({campaign: 1});

但是 mongodb 不使用索引。任何人都知道是否可以聚合框架使用索引,如何索引这个查询。

4

3 回答 3

12

这是一个较晚的答案,但由于$group在 Mongo 4.0 版中仍然不会使用索引,它可能对其他人有帮助。

要显着加快聚合速度,请执行$sortbefore $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,聚合需要几秒钟。

于 2019-06-03T12:57:01.420 回答
7

$group运算符不是当前将使用索引的运算符之一。这样做的操作员列表(从 2.2 开始)是:

$match
$sort
$limit
$skip

从这里:

http://docs.mongodb.org/manual/applications/aggregation/#pipeline-operators-and-indexes

根据 gist 中发生的产量数量,我假设您要么有一个非常活跃的实例,要么当您进行分组时,很多这些数据不在内存中(它通常也会在页面错误时产生),因此1.8s

请注意,即使$group可以使用索引,并且您的索引涵盖了所有被分组的内容,它仍然需要对索引进行完整扫描以进行分组,并且无论如何可能不会太快。

于 2012-11-20T03:28:26.773 回答
0

$group不使用索引,因为它不必。当您使用$group您的项目时,您实际上$group是在使用您$group_id. 如果您使用了与$group's匹配的索引_id,您仍然需要遍历索引中的所有文档,因此工作量相同。

于 2014-09-13T23:37:09.237 回答