MongoDB學習筆記——彙總
最近要去的新項目使用mysql,趁著還沒忘記,總結記錄以下MongoDB的彙總。
彙總是泛指各種可以處理批量記錄並返回計算結果的操作。MongoDB提供了豐富的彙總操作,用於對資料集執行計算操作。在 mongod 執行個體上執行彙總操作可以大大簡化應用的代碼,並降低對資源的消耗。
在MongoDB中,像查詢之類的彙總操作都是使用 集合 中的文檔作為輸入,最終的結果會輸出一個或者多個文檔。
彙總管道
彙總管道是一個基於資料處理管道概念的架構。通過使用一個多階段的管道,將一組文檔轉換為最終的彙總結果。(aggregate詳細)
彙總管道是映射化簡的一個替代方案。而且對於彙總任務來說,彙總管道是一種優選的解決方案,因為映射化簡的複雜度可能無法保證。
彙總管道的每個步驟可以使用的記憶體最多是100MB。如果某個步驟超過了這個限制,MongoDB就會報錯了。如果需要處理大量資料,可以使用 allowDiskUse 這個選項,此時管道會把資料寫入臨時檔案。
有的管道階段可以使用管道運算式作為運算子。管道運算式可以對輸入文檔做指定的轉換。管道運算式使用一個文檔結構體,並且可以包含其他的運算式 。
管道運算式只可以操作當前管道中的文檔,不能訪問其他的文檔:運算式操作可以在記憶體中完成對文檔的轉換。
一般來說,運算式是無狀態的,並且僅在彙總過程中處於計算狀態,除了累計操作符運算式。
使用 $group 操作符的累計操作,需要在管道處理文檔的過程中維護自己的狀態(例如總數、最大值、最小值和相關資料)。
映射化簡
映射化簡是一種將大量資料轉換為有價值的*彙總*結果的資料處理方式。在MongoDB中,使用mapReduce 命令來執行映射化簡的操作。
請看下面的映射化簡操作:
在這個映射化簡操作中,MongoDB對每個輸入文檔(例如集合中滿足查詢條件的文檔)執行了*map*操作。映射操作輸出了索引值對結果。對那些有多個值的關鍵字,MongoDB執行*reduce*操作,收集並壓縮了最終的彙總結果。然後MongoDB把結果儲存到一個集合中。化簡函數還可以把結果輸出到*finalize*函數,進一步對彙總結果做處理,當然這步是可選的。
在MongoDB中,所有的映射化簡函數都是使用JavaScript編寫,並且運行在 mongod 進程中。映射化簡操作使用一個集合中文檔作為*輸入*,並且可以在映射階段之前執行任意的排序和限定操作。mapReduce 命令可以把結果作為一個文檔來返回,也可以把結果寫入集合。輸入集合和輸出集合可以是分區的。
如果選擇映射化簡操作即時返回結果,這些文檔一定要在 BSON文檔大小 限制以內,當前這個限制是16MB。
單一用途的彙總
彙總指的是一大類對資料集執行運算的方法,這些方法對輸入資料執行特定的步驟從而計算出一個結果。MongoDB提供了一組對資料集執行特定操作的彙總方法。
儘管與彙總管道和映射化簡比起來,它們的使用範圍有限,但是這些方法的名稱很直觀的表達了它的功能,非常易於理解使用。
1) 總數
MongoDB可以返回符合查詢條件的文檔總數。除了 count 命令, mongo 指令碼程式中的 count() 方法和 cursor.count() 方法都可以得到文檔總數。
例子
現在有一個名為 records 的集合中 只有 下面這些文檔:
{ a: 1, b: 0 }{ a: 1, b: 1 }{ a: 1, b: 4 }{ a: 2, b: 2 }
下面的操作會統計集合中的文檔個數,並最終返回數字 4:
db.records.count()
下面的操作會統計欄位 a 的值是 1 的文檔個數,最終返回 3:
db.records.count({a: 1})
2) 去除重複
去除重複 操作會返回查詢到的指定欄位值不重複的記錄。在 mongo 指令碼程式中,使用 distinct 命令或者 db.collection.distinct() 方法執行去重。請看下面的去除重複的例子:
例子
現在有一個名為 records 的集合中 只有 下面這些文檔:
{ a: 1, b: 0 }{ a: 1, b: 1 }{ a: 1, b: 1 }{ a: 1, b: 4 }{ a: 2, b: 2 }{ a: 2, b: 2 }
請看下面使用 db.collection.distinct() 方法對欄位 b 進行去除重複的操作:
db.records.distinct("b")
這個操作的結果是:
[ 0, 1, 4, 2 ]
3) 分組
分組 操作會把查詢到的文檔按照給定的欄位值進行分組。分組操作會返回一個文檔數組,其中的每個文檔包含了一組文檔的計算結果。
可以在 mongo 指令碼程式中通過 group 命令或者 db.collection.group() 方法來使用分組的功能。
group 命令不能在分區集合上運行。特別需要注意一點, group 操作的結果集大小不能超過16MB。
例子
現在有一個名為 records 的集合,它包含有如下文檔:
{ a: 1, count: 4 }{ a: 1, count: 2 }{ a: 1, count: 4 }{ a: 2, count: 3 }{ a: 2, count: 1 }{ a: 1, count: 5 }{ a: 4, count: 4 }
請考慮用 group 命令對集合中的文檔進行分組,分組條件是欄位 a 值小於 3 ,同時需要對每組的count 欄位計數:
db.records.group({ key: {a: 1}, cond: {a: {$lt: 3}}, reduce: function(cur, result) { result.count += cur.count }, initial: {count: 0}})
這次分組操作的結果是:
[ {a: 1, count: 15}, {a: 2, count: 4}]
更多MongoDB相關內容可以看看以下的有用連結:
MongoDB 3.0 正式版發布下載
CentOS編譯安裝MongoDB
CentOS 編譯安裝 MongoDB與mongoDB的php擴充
CentOS 6 使用 yum 安裝MongoDB及伺服器端配置
Ubuntu 13.04下安裝MongoDB2.4.3
MongoDB入門必讀(概念與實戰並重)
Ubunu 14.04下MongoDB的安裝指南
《MongoDB 權威指南》(MongoDB: The Definitive Guide)英文文字版[PDF]
Nagios監控MongoDB分區叢集服務實戰
基於CentOS 6.5作業系統搭建MongoDB服務
MongoDB 的詳細介紹:請點這裡
MongoDB 的:請點這裡
本文永久更新連結地址: