MongoDB 中聚合(aggregate)主要用于處理資料(諸如統計平均值,求和等),并傳回計算後的資料結果。
有點類似 SQL 語句中的 count(*)。
MongoDB中聚合的方法使用aggregate()。
aggregate() 方法的基本文法格式如下所示:
集合中的資料如下:
現在我們通過以上集合計算每個作者所寫的文章數,使用aggregate()計算結果如下:
以上執行個體類似sql語句:
在上面的例子中,我們通過字段 by_user 字段對資料進行分組,并計算 by_user 字段相同值的總和。
下表展示了一些聚合的表達式:
表達式
描述
執行個體
$sum
計算總和。
db.mycol.aggregate([{\(group : {_id : "\)by_user", num_tutorial : {\(sum : "\)likes"}}}])
$avg
計算平均值
db.mycol.aggregate([{\(group : {_id : "\)by_user", num_tutorial : {\(avg : "\)likes"}}}])
$min
擷取集合中所有文檔對應值得最小值。
db.mycol.aggregate([{\(group : {_id : "\)by_user", num_tutorial : {\(min : "\)likes"}}}])
$max
擷取集合中所有文檔對應值得最大值。
db.mycol.aggregate([{\(group : {_id : "\)by_user", num_tutorial : {\(max : "\)likes"}}}])
$push
在結果文檔中插入值到一個數組中。
db.mycol.aggregate([{\(group : {_id : "\)by_user", url : {\(push: "\)url"}}}])
$addToSet
在結果文檔中插入值到一個數組中,但不建立副本。
db.mycol.aggregate([{\(group : {_id : "\)by_user", url : {\(addToSet : "\)url"}}}])
$first
根據資源文檔的排序擷取第一個文檔資料。
db.mycol.aggregate([{\(group : {_id : "\)by_user", first_url : {\(first : "\)url"}}}])
$last
根據資源文檔的排序擷取最後一個文檔資料
db.mycol.aggregate([{\(group : {_id : "\)by_user", last_url : {\(last : "\)url"}}}])
管道在Unix和Linux中一般用于将目前指令的輸出結果作為下一個指令的參數。
MongoDB的聚合管道将MongoDB文檔在一個管道處理完畢後将結果傳遞給下一個管道處理。管道操作是可以重複的。
表達式:處理輸入文檔并輸出。表達式是無狀态的,隻能用于計算目前聚合管道的文檔,不能處理其它的文檔。
這裡我們介紹一下聚合架構中常用的幾個操作:
$project:修改輸入文檔的結構。可以用來重命名、增加或删除域,也可以用于建立計算結果以及嵌套文檔。
\(match:用于過濾資料,隻輸出符合條件的文檔。\)match使用MongoDB的标準查詢操作。
$limit:用來限制MongoDB聚合管道傳回的文檔數。
$skip:在聚合管道中跳過指定數量的文檔,并傳回餘下的文檔。
$unwind:将文檔中的某一個數組類型字段拆分成多條,每條包含數組中的一個值。
$group:将集合中的文檔分組,可用于統計結果。
$sort:将輸入文檔排序後輸出。
$geoNear:輸出接近某一地理位置的有序文檔。
1、$project執行個體
這樣的話結果中就隻還有_id,tilte和author三個字段了,預設情況下_id字段是被包含的,如果要想不包含_id話可以這樣:
2.$match執行個體
<code>$match</code>用于擷取分數大于70小于或等于90記錄,然後将符合條件的記錄送到下一階段$group管道操作符進行處理。
3.$skip執行個體
經過$skip管道操作符處理後,前五個文檔被"過濾"掉。
這樣子也是可行的。也就是說非0也可以進行表示顯示該字段,負數也可以表示顯示該字段。
按日、按月、按年、按周、按小時、按分鐘聚合操作如下:
時間關鍵字如下:
$dayOfYear: 傳回該日期是這一年的第幾天(全年 366 天)。
$dayOfMonth: 傳回該日期是這一個月的第幾天(1到31)。
$dayOfWeek: 傳回的是這個周的星期幾(1:星期日,7:星期六)。
$year: 傳回該日期的年份部分。
$month: 傳回該日期的月份部分( 1 到 12)。
$week: 傳回該日期是所在年的第幾個星期( 0 到 53)。
$hour: 傳回該日期的小時部分。
$minute: 傳回該日期的分鐘部分。
$second: 傳回該日期的秒部分(以0到59之間的數字形式傳回日期的第二部分,但可以是60來計算閏秒)。
$millisecond:傳回該日期的毫秒部分( 0 到 999)。
$dateToString: { $dateToString: { format: , date: } }。
這裡有一個小細節:當 match 條件和 group 同時存在時,順序會影響檢索結果,必須先寫 match 在前面。
這兩個語句執行的結果會不一樣,新手需要在意。