在聚合管道中执行$ match阶段时如何添加限制

时间:2019-01-23 00:34:33

标签: mongodb aggregation-framework

在执行find()查询时,我可以传递限制和排序等选项。我认为这意味着数据库将在找到限制数量的文档后停止尝试过滤匹配的文档。

当尝试通过聚合管道完成相同的操作时,我将来自find()的查询作为$ match阶段,但我无法指定限制。

$ limit的问题在于它仅在下一阶段发生,因此mongo将在将其传递到下一阶段之前已经处理了集合中的每个文档,随着集合大小的增加,它会变得非常慢。 / p>

1 个答案:

答案 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阶段完成其过程才能限制输出

查看Explain ResultsAggregation Pipeline Optimization了解更多信息。