1

我有一个相当小的 63k 文档数据集(总共 2.5GB)。文件示例:

{
     _id : "[uniqueId]",
     FormId : 10,
     Name : "Name of form",
     IsComplete : true,
     Sections : [ many sections and can be large ]
}

我想通过 FormId 获取文档的总数。我在这个查询上得到了快速的结果(0.15 秒):

db.getCollection('collection').aggregate([
     { $sort : { FormId : 1 } }, //Index exists on FormId
     { $group : { _id : "$FormId", count : { $sum : 1 } } },
     { $sort : { "count" : -1 } }
])

我的问题是我需要计算 {“IsComplete”:true } 所在的文档。我在两个属性上都建立了 2 个索引,但我意识到使用 $match 运算符会扫描所有文档。那么如何有效地过滤 $group 计数呢?

4

1 回答 1

3

有效的方法是

通过使用 $match 过滤文档以仅将匹配的文档传递到下一个管道。通过将 $match 放在管道的最开始,查询可以利用索引。

使用 $project 将仅包含必填字段的文档传递到管道中的下一个阶段,这将进一步减少到下一个管道的数据。

db.getCollection('collection').aggregate([ 
  { $match: {"IsComplete":true} },
  { $project: {"IsComplete":1, "FormId":1}},
  { $group : { _id : "$FormId", count : { $sum : 1 } } },
  { $sort : { "count" : -1 } }
])
于 2016-09-16T18:25:39.437 回答