1. 聚合aggregate 聚合主要用於計算數據,類似sql中的sum()、avg() 語法: db.集合名稱.aggregate([{管道:{表達式}}]) stu準備的數據: 1.1 管道 管道在Unix和Linux中一般用於將當前命令的輸出結果作為下一個命令的輸入。 ps ajx | gre ...
1. 聚合aggregate
聚合主要用於計算數據,類似sql中的sum()、avg()
語法:
db.集合名稱.aggregate([{管道:{表達式}}])
stu準備的數據:
db.stu.insertMany([ { name: "gj",gender:true, age: 18}, { name: "gj1",gender:true, age: 28}, { name: "hr",gender:false, age: 18}, { name: "hr1",gender:false, age: 28} ])
1.1 管道
管道在Unix和Linux中一般用於將當前命令的輸出結果作為下一個命令的輸入。
ps ajx | grep mongo
在mongodb中,管道具有同樣的作用,文檔處理完畢後,通過管道進行下一次處理。
常用管道:
$group:將集合中的文檔分組,可用於統計結果。
$match:用於過濾數據,只輸出符合條件的文檔。$match使用MongoDB的標準查詢操作。
$project:修改輸入文檔的結構。可以用來重命名、增加或刪除域,也可以用於創建計算結果以及嵌套文檔。
$sort:將輸入文檔排序後輸出。
$limit:用來限制MongoDB聚合管道返回的文檔數。
$skip:在聚合管道中跳過指定數量的文檔,並返回餘下的文檔。
$unwind:將文檔中的某一個數組類型欄位拆分成多條,每條包含數組中的一個值。
$geoNear:輸出接近某一地理位置的有序文檔。
1.2 表達式
處理輸入文檔並輸出。
語法:
表達式:'$列名'
常用表達式:
$sum:計算總和,$sum:同count表示計數
$avg:計算平均值
$min:獲取最小值
$max:獲取最大值
$push:在結果文檔中插入一個數組中,數組內容為選中欄位
$first:根據資源文檔的排序獲取第一個文檔數據
$last:根據資源文檔的排序獲取最後一個文檔數據
1.3 $group
將集合中的文檔分組,可用於統計結果。
_id表示分組的依據,使用某個欄位的格式為‘$欄位’
實例:
統計男生、女生的總人數:
db.stu.aggregate([ {$group:{_id:'gender',counter:{$sum:1}}} ])
統計學生性別及學生姓名:
db.stu.aggregate([ {$group:{_id:'gender',counter:{$push:'$name'}}} ])
使用$$ROOT可以將文檔內容加入到結果集的數組中:
db.stu.aggregate([ {$group:{_id:'gender',name:{$push:'$$ROOT'}}} ])
將集合中所有文檔分為一組。
求學生總人數、平均年齡:
db.stu.aggregate([ {$group:{_id:null,counter:{$sum:1},avgAge:{$avg:'$age'}}} ])
1.4 $match
用於過濾數據,只輸出符合條件的文檔。
使用MongoDB的標準查詢操作。
實例:
查詢年齡大於20的學生:
db.stu.aggregate([ {$match:{age:{$gt:20}}} ])
查詢年齡大於20的男生、女生人數。
db.stu.aggregate([ {$match:{age:{$gt:20}}}, {$group:{_id:'$gender',counter:{$sum:1}}} ])
1.5 $project
修改輸入文檔的結構,如重命名、增加、刪除欄位、創建計算結果。
實例:
查詢學生的姓名、年齡。
db.stu.aggregate([ {$project:{_id:0,name:1,age:1}} ])
查詢男生、女生人數,輸出人數。
db.stu.aggregate([ {$group:{_id:'$gender',counter:{$sum:1}}}, {$project:{_id:0,counter:1}} ])
1.6 $sort
將輸入文檔排序後輸出。
實例:
查詢學生學習,按年齡升序。
db.stu.aggregate([ {$sort:{age:1}} ])
查詢男生、女生人數,按人數降序。
db.stu.aggregate([ {$group:{_id:'$gender',counter:{$sum:1}}}, {$sort:{counter:-1}} ])
1.7 $limit
限制聚合管道返回的文檔數。
查詢2條學生信息。
db.stu.aggregate([ {$limit:2} ])
1.8 $skip
跳過指定數量的文檔,並返回餘下的文檔。
查詢從第3條開始的學生信息。
db.stu.aggregate([ {$skip:2} ])
統計男生、女生人數,按人數升序,取第二條數據。
db.stu.aggregate([ {$group:{_id:'$gender',counter:{$sum:1}}}, {$sort:{counter:1}}, {$skip:1}, {$limit:1} ])
註意順序:先寫skip,再寫limit。
1.9 $unwind
將文檔中的某一個數組類型欄位拆分成多條,每條包含數組中的一個值。
語法1:
對某欄位值進行拆分。
db.集合名稱.aggregate([{$unwind:'$欄位名稱'}])
構造數據:
db.t2.insert({_id:1,title:'t-shirt',size:['M','L','S']})
查詢:
db.t2.aggregate([{$unwind:'$size'}])
語法2:
對某欄位值進行拆分。
處理空數組、非數組、無欄位、null情況。
db.集合名稱.aggregate([{ $unwind:{ path:'$欄位名稱', preserveNullAndEmptyArrays:<boolean> #防止數據丟失 }])
構造數據:
db.t3.insert([ {_id:1,"item":"a",size:["M","L","S"]}, {_id:2,"item":"b",size:[]}, {_id:3,"item":"c",size:"M"}, {_id:4,"item":"d"}, {_id:5,"item":"e",size:null} ])
使用語法1查詢:
db.t3.aggregate([{$unwind:'$size'}])
使用語法2查詢 :
db.t3.aggregate([ {$unwind:{path:'$size',preserveNullAndEmptyArrays:true}} ])