2016-09-16 28 views
0

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

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

我想通过FormId获取文档的总数。我对这个查询得到了快速的结果(.15sec):

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

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

+0

这里你不需要第一个'$ sort'阶段。 – styvane

+0

@Styvane没有$ sort阶段$组需要10秒钟才能完成。为什么会发生?从$ sort开始使用索引。 – JayJohnsonDesigns

回答

0

有效的方法是

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

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

db.getCollection('collection').aggregate([ 
    { $match: {"IsComplete":true} }, 
    { $project: {"IsComplete":1, "FormId":1}}, 
    { $group : { _id : "$FormId", count : { $sum : 1 } } }, 
    { $sort : { "count" : -1 } } 
]) 
+0

当我首先运行$匹配时,管道需要10秒才能完成。我在FormId和IsComplete上有两个单独的索引。为什么需要很长时间才能完成? – JayJohnsonDesigns

+0

由于“IsComplete”索引没有很多独特的值,因此索引一个数量较少的独立值的字段并不值得去做。另一个因素是索引如何划分您的数据。如果您有大约一半的真实值和一半假的,那么它会有所帮助。 – RootHacker

+0

这里的性能还将取决于“IsComplete”的值与您击中查询的值的比率,如果您查询true和数据比率为30:70而不是true:false,那么它可能会减少一些时间将只处理一小部分数据。 – RootHacker