MongoDB: 聚集管道,
在MongoDB2.2新出現的。
聚集管道式基於資料處理管道概念建模的資料聚集架構。文檔進入一個多階段能將該文檔轉化為聚集結果的管道。
聚集管道提供了map-reduce方法了替代物,並在很多聚集任務中是首選的方案,因為map-reduce的複雜性可能是你不希望看到的。
是一個帶注釋的聚集管道的操作,有兩個階段:$match和$group
聚集管道在值的類型和結果大小上有很多限制。下面簡單介紹,
聚集操作在使用aggregate命令時有的限制:
聚集管道不是在下列類型的值上進行操作:Symbol,Minkey,MaxKey,DBRef,Code和CodeWSrope
(在MongoDB2.4版本解除了對Binary類型的限制。在MongoDB2.2,管道不能對Binary類型資料操作)
如果aggregate命令返回的單個文檔保護完整的結果集,則該命令在結果集超過BSON Document Size限制時會產生一個錯誤,目前的大小是16M。為了管理超過這一限制的結果集,aggregate命令當命令返回一個遊標(cursor)或把結果儲存在一個collection裡時,能夠返回任意大小的結果集。
(在MongoDB2.6,aggregate命令返回一個遊標或把結果存在一個collection時,能不受這個大小限制。db.collection.aggregate()返回一個遊標,能返回任意大小的結果集。)
在MongoDB2.6有了變化。
管道階段在RAM有100M的限制。如果超過這一限制,MongoDB會出錯。為了允許操作大型資料,可以使用allowDiskUse選項來時聚集管道階段能往臨時檔案寫資料。
管道
管道,顧名思義就是來自集合的文檔通過一個聚集管道的旅行,當通過其中時該管道能轉化這些對象。對熟悉Unix shells命令的(如 bash),這個概念和管道(pipe)很類似。
MongoDB的聚集管道以一個集合的文檔開始,流動文檔從一個管道操作(pipeline operator)到下一個來處理文檔。在管道的每一個操作符在文檔經過管道時都會轉化文檔。管道操作符不需要為每一個輸入文檔產生一個輸出文檔。操作符可以產生新文檔也能過濾文檔。管道操作能在一個管道裡面重複。
管道運算式
每一個管道操作符接受一個管道運算式作為運算元。管道運算式指出應用在輸入文檔的轉化過程。運算式有一個文檔(document)結構,並包含欄位,值和操作符。
管道運算式只能操作在管道中的當前文檔,不能引用在其他文檔的資料:運算式提供了記憶體(in-memory)文檔轉化。
一般的,運算式是無狀態的,只在聚集過程時有一個例外:Accumulation expressions。累加運算式,使用$group管道,維持他們的狀態(如,totals,maximums,mininums和相關資料)作為通過管道的文檔過程。
聚集管道行為
在MongoDB,aggregate命令操作單個集合,並在邏輯上傳遞整個文檔給聚集管道。為了最佳化這個操作,在可能的情況下,應該使用下面策略來避免掃描整個集合。
$match和$sort管道操作符能夠利用索引的優勢,如果他們在管道的開始位置出現。
(在Mongo2.4新出現的:$geoNear管道操作符能利用地理索引的優勢。當使用$geoNear,$geoNear必須在聚集管道的第一階段出現。)
即使管道使用了索引,彙總操作依然要訪問實際的文檔。比如,索引不能完全覆蓋聚集管道。
(在Mongo2.6之前的版本,對規模非常小的選擇情況,索引能夠覆蓋管道)
提前過濾
如果你的聚集應用僅需要一個集合的一個資料子集,使用 $match,$limit,$skip階段在文檔進入管道時去限制文檔.當被放置在管道的開始,$match操作符使用合適的索引去掃描集合匹配的文檔.
在管道的開始緊跟著$sort階段放置$match在邏輯上等價於一個使用排序的單一查詢,並可以使用索引.如果可能的話,把$match放置在管道的開頭.