天天看點

MongoDB 聚合

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 在前面。

這兩個語句執行的結果會不一樣,新手需要在意。