aggregate聚合是經過管道操做實現的。聚合管道里的每一步輸出,都會做爲下一步的輸入,每一步在輸入文檔執行完操做後生成輸出文檔。mongodb
聚合管道: 數組
$project
修改輸入文檔的結構。能夠用來重命名、增長或刪除域,也能夠用於建立計算結果以及嵌套文檔。對應project()
方法 spa
$match
用於過濾數據,只輸出符合條件的文檔。$match使用MongoDB的標準查詢操做。對應match()
。 code
$limit
用來限制MongoDB聚合管道返回的文檔數。對應limit()
方法 blog
$skip
在聚合管道中跳過指定數量的文檔,並返回餘下的文檔。對應skip()
。 排序
$unwind
將文檔中的某一個數組類型字段拆分紅多條,每條包含數組中的一個值。對應unwind()
方法 ip
$group
將集合中的文檔分組,可用於統計結果。對應group()
方法 資源
$sort
將輸入文檔排序後輸出。對應sort()
方法 文檔
$geoNear
輸出接近某一地理位置的有序文檔。對應near()
。 get
$group
表達式說明:
$sum
計算總和
$avg
計算平均值
$min
獲取每一組集合中全部文檔對應值得最小值
$max
獲取每一組集合中全部文檔對應值得最大值
$push
在結果文檔中插入值到一個數組中
$addToSet
在結果文檔中插入值到一個數組中,但不建立副本
$first
根據資源文檔的排序獲取第一個文檔數據
$last
根據資源文檔的排序獲取最後一個文檔數據
舉例說明aggregate聚合 $group使用
商品屬性:_id, createTime, nowPriceL, nowPriceH, number
統計每一天內店鋪商品的最低價和最高價,平均最低價,
執行完$match管道後,獲得的查詢結果會輸入到$project管道,執行完$project管道,獲得的結果格式爲{day,nowPriceL,nowPriceH},把這個結果輸入$group管道, $group管道執行完畢,輸出的結果輸入到$sort管道,$sort執行完畢,輸出最終結果集
Goods.aggregate([ { $match: { number: {$gte:100} //匹配number>=100的記錄 } }, { $project : { day : {$substr: [{"$add":["$createTime", 28800000]}, 0, 10] },//時區數據校訂,8小時換算成毫秒數爲8*60*60*1000=288000後分割成YYYY-MM-DD日期格式便於分組 "nowPriceL": 1, //設置原有nowPriceL爲1,表示結果顯示原有字段nowPriceL "nowPriceH":1, //設置原有nowPriceH爲1,表示結果顯示原有字段nowPriceH avgNowPriceL:{$toDouble:"$nowPriceL"},//把最低價轉換爲小數 avgNowPriceH:{$toDouble:"$nowPriceH"},//把最高價轉換爲小數 "dayNumber":1 //每組內有多少個成員 }, }, { $group: { _id:"$day", //按照$day進行分組(一組爲1天) nowPriceL:{$min: "$nowPriceL"}, //查找組內最小的nowPriceL nowPriceH:{$max: "$nowPriceH"}, //查找組內最大的nowPriceH avgNowPriceL:{$avg:"$avgNowPriceL"},//統計每一天內店鋪商品的平均最低價 avgNowPriceH:{$avg:"$avgNowPriceH"},//統計每一天內店鋪商品的平均最高價 dayNumber:{$sum:1} } }, { $sort: { nowPriceL: 1//執行完 $group,獲得的結果集按照nowPriceL升序排列 } }]).exec(function (err, goods){ //返回結果 console.log(goods); });
注意:
mongoodb存儲的數據是按照世界時間存儲的,所以進行分割操做時須要對時間進行時區校訂,使用$add加上時區差8小時(毫秒數)才能獲得正確的數據
$substr: [ <string>, <start>, <length> ] }
https://docs.mongodb.com/manual/reference/operator/aggregation/toDouble/#exp._S_toDouble