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命令操作單個集合,並在邏輯上傳遞整個文檔給聚集管道。爲了優化這個操作,在可能的情況下,應該使用下面策略來避免掃描整個集合。

  1. 管道操作符和索引

$match和$sort管道操作符能夠利用索引的優勢,如果他們在管道的開始位置出現。

(在Mongo2.4新出現的:$geoNear管道操作符能利用地理索引的優勢。當使用$geoNear,$geoNear必須在聚集管道的第一階段出現。)

即使管道使用了索引,聚合操作依然要訪問實際的文檔。比如,索引不能完全覆蓋聚集管道。

(在Mongo2.6之前的版本,對規模非常小的選擇情況,索引能夠覆蓋管道)


提前過濾

如果你的聚集應用僅需要一個集合的一個數據子集,使用 $match,$limit,$skip階段在文檔進入管道時去限制文檔.當被放置在管道的開始,$match操作符使用合適的索引去掃描集合匹配的文檔.

在管道的開始緊跟着$sort階段放置$match在邏輯上等價於一個使用排序的單一查詢,並可以使用索引.如果可能的話,把$match放置在管道的開頭.


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章