在执行find()查询时,我可以传递限制和排序等选项。我认为这意味着数据库将在找到限制数量的文档后停止尝试过滤匹配的文档。
当尝试通过聚合管道完成相同的操作时,我将来自find()的查询作为$ match阶段,但我无法指定限制。
$ limit的问题在于它仅在下一阶段发生,因此mongo将在将其传递到下一阶段之前已经处理了集合中的每个文档,随着集合大小的增加,它会变得非常慢。 / p>
答案 0 :(得分:1)
聚合框架的作用就像流一样,因此,如果您的管道中有一个$limit
阶段,一旦达到限制,它将停止处理。
例如:
> db.test.find()
{ "_id": 0 }
{ "_id": 1 }
{ "_id": 2 }
{ "_id": 3 }
{ "_id": 4 }
假设我要使用$match
阶段,然后再使用$limit
阶段。在聚合上使用explain()
:
> db.test.explain('executionStats').aggregate([
{$match: {_id: {$lte: 3}}},
{$limit: 1}
])
...
"executionStats": {
"executionSuccess": true,
"nReturned": 1,
"executionTimeMillis": 0,
"totalKeysExamined": 1,
"totalDocsExamined": 1,
...
说明输出显示,由于处于totalKeysExamined: 1
阶段,MongoDB仅检查了1个键(totalDocsExamined: 1
)和1个文档(nReturned: 1
)才能返回1个文档($limit
)。 。尽管我将其指定为匹配_id <= 3
,但应该选择4个文档。
请注意,除了$group
之类的阶段外,大多数阶段都是这样工作的,这些阶段需要收集所有必需的文档才能对其进行分组。将$limit
放在$group
之后将不会使$limit
阶段充当流,因为它必须等待$group
阶段完成其过程才能限制输出