2013-03-25 50 views
6

http://docs.mongodb.org/manual/core/indexes/#multikey-indexes,可以使用多鍵索引在數組字段上創建索引。 http://docs.mongodb.org/manual/applications/aggregation/#pipeline-operators-and-indexes列舉了如何在聚合框架中使用索引的一些方法。但是,有時可能需要在陣列字段上執行$unwind才能執行$group。我的問題是,多鍵索引(或使用這種數組字段的任何索引)是否仍然可以在管道中間運行後使用?聚合流水線和索引

回答

11

一般情況下,只可以展平到一個正常的查詢($match$limit$sort$skip)管道運營商將能夠使用上收集的指標。這是操作員在2.4中添加的$geoNear必須處於流水線開始的原因之一。

一旦您使用$project$group$unwind變更文檔,索引不再有效/可用。

如果您在陣列字段上有索引,則仍然可以在$unwind之前使用它,以加快文檔到流水線的選擇速度,然後再用第二個$match優化所選文檔。

考慮像證件:

{ tags: [ 'cat', 'bird', 'blue' ] } 

隨着tags的索引。

如果你只是想組標籤與b開始,那麼你可以像執行聚合:

{ pipeline: [ 
     { $match : { tags : /^b/ } }, 
     { $unwind : '$tags' }, 
     { $match : { tags : /^b/ } }, 
     /* the rest */ 
    ] } 

第一$match確實使用上tags指數的粗糧搭配。

$unwind之後的第二個匹配項將無法使用索引(上面的文檔現在是3個文檔),但可以評估每個文檔以篩選出創建的額外文檔(要刪除{tags: 'cat'})。

HTH - Rob。

+0

感謝您的回答。然而,我發現「一旦你用......'$ unwind'改變文檔,那麼索引就不再有效了」與其他答案相矛盾。你能解釋這是爲什麼嗎? – MervS 2013-03-25 03:28:55

+0

對不起,應該已經更清楚了。我會嘗試在一秒內編輯它,但第一場比賽使用索引,第二場比賽不會。 – 2013-03-26 00:23:04

0

嗯@Rob確實得到正確的答案,但我看到他如何能導致你在錯誤的道路一點:如果你有一個數組中的一個索引,你仍可以前後使用

$展開以加速文檔到流水線的選擇,然後進一步優化選定的文檔。

基本上,例如他給出:

{ pipeline: [ 
     { $match : { tags : /^b/ } }, 
     { $unwind : '$tags' }, 
     { $match : { tags : /^b/ } }, 
     /* the rest */ 
    ] } 

將不使用多鍵索引過去$unwind。因此,它將能夠搜索標籤名稱以b開頭的所有ROOT文檔,但是它將無法使用$unwind,然後使用索引過濾掉第二個$match中的子文檔。

$match只適用於突變前的索引。

所以基本上,一旦你已經改變了文檔並將其加載到管道上,那麼當前幾乎不可能使用索引。