2016-09-16 91 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