MongoDB
聚合 aggregate
聚合操作就是把源數據集放到管道里加以處理得到統計後的結果
db.collectionName.aggregate([{ 管道 :{ 表達式 }}])
常用管道:
$group
:給集合的文檔分組,可用於統計結果,相當於GROUP BY$match
:過濾數據,只輸出符合條件的文檔,相當於HAVING$project
:選出來原始文檔中的某些字段$sort
:將輸入排序後輸出$limit
$skip
$unwind
:將數組類型的字段進行拆分
常用表達式:
$sum
:計算綜合,$sum:1
和count一樣表示計數$avg
,$min
,$max
等等類似$push
:在結果文檔中插入值到一個數組當中去$first / $last
:獲取第一個/最後一個文檔數據
分組 $group
:
counter:累計器
db.hi.aggregate([{
$group: {
_id: "$gender", // 基於誰分組 ,①先把gender一樣的分組(分出男女兩組,每組若干個文檔)
//_id:null // 整個集合分爲一組
counter: { // 結果字段的統計方式(計數、求和、求平均數) ,②再分別在每個組內統計:
$sum: 1 // $sum: 1 就是 sql裏的count(*) ,計數每組文檔數量
//$avg:"$age", // 該組所有成員的某個鍵對應的平均值(該組年齡的平均值)
//$last:"$age" // 該組所有成員某個鍵對應的最後一個值(該組年齡的最後一個值,排序後有意義)
//$push:"$age" // 該組所有成員某個鍵對應的值插入到一個數組裏(該組所有年齡插入數組)
//$push:"$$ROOT" // 該組所有成員的完整文檔插入到一個數組裏
}
}
}]
過濾 $match
:
和find方法一樣,find是不能進行統計的,$match可以統計
管道內先寫match後寫group,
db.collection.aggregate([{
$match: {
age: {
$gt: 20 // 查詢到年齡比20大的文檔
}
}
}])
投影 $project
:
把結果集當中的一部分拿出來顯示:
db.collection.aggregate([
{ $match :{ age :{ $gt:20}}},
{ $group :{ _id:"$gender",counter :{ $sum:1}}},
{ $project :{ _id:0, counter : 1}}, // _id就是上面的gender字段,0代表不顯示該字段,1代表顯示該字段
])
排序 $sort
:
db.collection.aggregate([
{ $match :{ age:{ $gt : 20 }}},
{ $group :{ _id:"gender",counter :{ $sum:1 }}},
{ $project :{ _id:0, counter :1 }}, // 0代表不顯示該字段,1代表顯示該字段
{ $sort :{ counter : 1 }}, // 把指定字段按 :1 順序排列 -1 倒序排列
])
跳過$skip
範圍$limit
:
db.collection.aggregate([
{ $match :{ age :{ $gt : 20 }}},
{ $group :{ _id:"gender", counter :{ $sum : 1 }}},
{ $project :{ _id:0 , counter : 1 }},
{ $sort :{ counter : 1 }},
{ $skip : 1 }, //有順序規定
{ $limit : 1 }
])
拆分數組 $unwind
:
逆group操作,把數組拆分
{
field1: value1,
field2: [item1, item2]
}
拆分成:
{
field1: value1,
field2: item1
}
{
field1: value1,
field2: item2
}
db.collection.aggregate([
{
$unwind : {
path : "$size", // 需要被拆分的數組值的對應字段名
preserveNullAndEmptyArrays : true // 防止非數組數據丟失
}
}
])
實例:
聚合數據的反拆:
db.collection.aggregate([
{
$group:
{
_id: "gender",
counter: { $sum: 1 },
docs: { $push: "$$ROOT" }
}
},
{
$project:
{
_id: 0, counter: 1, docs: 1
}
},
{
$unwind : {
path : "$docs", // 這樣就拿到了所有管道操作以後的源數據集
preserveNullAndEmptyArrays : true
}
}
])