3.4.聚合
#3.4.1.什么是聚合娘锁?
MongoDB中聚合(aggregate)主要用于處理數(shù)據(jù)(諸如統(tǒng)計(jì)平均值,求和等)牙寞,并返回計(jì)算后的數(shù)據(jù)結(jié)果。有點(diǎn)類似sql語句中的 count(*)
例如上圖中一個集合中有9個文檔莫秆,通過count操作后碎税,輸出一個9,這種操作就是一個單一的聚合操作
#3.4.2.什么是聚合管道馏锡?
上面說到了單一的聚合操作雷蹂,那什么又是聚合管道呢?你可以把管道理解為流水線杯道,或者就是水管匪煌,把數(shù)據(jù)看作是水流,我們稱之為數(shù)據(jù)流党巾,管道中裝的都是數(shù)據(jù)萎庭,數(shù)據(jù)在管道中流動,數(shù)據(jù)在一個管道中經(jīng)過處理后可以傳遞到下一個管道齿拂,最終得到你想要的數(shù)據(jù)
請看官網(wǎng)例子:
在集合中有4條文檔數(shù)據(jù)驳规,經(jīng)過group來處理捻勉,$group的作用是對文檔進(jìn)行分組镀梭,分組后又根據(jù)amount字段求和,所以id為A123的最終結(jié)果是750(500+250)
#3.4.3.如何使用聚合管道操作
#1.aggregate() 方法
這個方法就是用來具體執(zhí)行管道操作的踱启,具體語法如下:
db.COLLECTION_NAME.aggregate(AGGREGATE_OPERATION)
官網(wǎng)例子:
db.orders.aggregate([
{$match: {status: "A"}},
{$group: {_id: "$cust_id", total: {$sum: "$amount"}}}
])
aggregate方法中傳入一個數(shù)組报账,這個數(shù)據(jù)中的每個元素就是一次聚合操作,第一個元素的操作執(zhí)行完后會傳遞給下個元素執(zhí)行埠偿,每個元素都是一個對象透罢,對象中的key就是管道操作符,例如:{match就是管道操作符冠蒋,對象中的value值就是管道表達(dá)式,例如:{$match: {status: "A"}},這里面的{status: "A"}就是管道表達(dá)式
#2.常用管道操作符
管道操作符 | 功能描述 |
---|---|
$project | 修改輸入文檔的結(jié)構(gòu)琐凭。可以用來重命名浊服、增加或刪除域统屈,也可以用于創(chuàng)建計(jì)算結(jié)果以及嵌套文檔 |
$match | 用于過濾數(shù)據(jù),只輸出符合條件的文檔 |
$limit | 用來限制MongoDB聚合管道返回的文檔數(shù) |
$skip | 在聚合管道中跳過指定數(shù)量的文檔牙躺,并返回余下的文檔 |
$sort | 條件排序 |
$group | 將集合中的文檔分組愁憔,可用于統(tǒng)計(jì)結(jié)果 |
$lookup | 用以引入其他集合的數(shù)據(jù),可以用來做關(guān)聯(lián)查詢 |
#3.管道表達(dá)式
前面我們已經(jīng)說過什么是管道表達(dá)式,例如:{_id: "sum: "
sum: "
sum就是一個表達(dá)式操作符乃秀,用于求和運(yùn)算
常見的表達(dá)式操作符如下:
表達(dá)式操作符 | 功能描述 |
---|---|
$addToSet | 將文檔的指定字段的值去重 |
$max | 求字段的最大值 |
$min | 求字段的最小值 |
$sum | 求和 |
$avg | 求平均值 |
$gt | 大于 |
$lt | 小于 |
$eq | 等于 |
#4.實(shí)際操作
準(zhǔn)備數(shù)據(jù)肛著,你可以將下列代碼直接拷貝到mongodb中執(zhí)行:
db.order.insert({"order_id":"1","uid":10001,"trade_no":"nd001","all_price":10,"all_num":9})
db.order.insert({"order_id":"2","uid":10002,"trade_no":"nd002","all_price":20,"all_num":8})
db.order.insert({"order_id":"3","uid":10003,"trade_no":"nd003","all_price":30,"all_num":7})
db.order_item.insert({"order_id":"1","title":"無線鼠標(biāo) 1","price":500,num:10})
db.order_item.insert({"order_id":"1","title":"無線鍵盤 2","price":600,num:11})
db.order_item.insert({"order_id":"1","title":"有線鍵盤 3","price":700,num:12})
db.order_item.insert({"order_id":"2","title":"蘋果","price":50,num:2})
db.order_item.insert({"order_id":"2","title":"香蕉","price":40,num:3})
db.order_item.insert({"order_id":"3","title":"牛奶","price":20,num:9})
db.order_item.insert({"order_id":"3","title":"面包","price":10,num:4})
#1.$project
通俗的說這個管道操作符可以用來篩選指定的字段
舉例:查詢出訂單信息,只顯示訂單號
db.order.aggregate([{$project:{_id: 0, order_id: 1}}])
#2.$match
通俗的說$match操作的作用就是查找滿足條件的數(shù)據(jù)
db.order.aggregate([{$project: {order_id: 1, all_price: 1}}, {$match: {"all_price": {$gt: 20}}}])
#3.$group
$group主要是用來進(jìn)行分組操作的
db.order_item.aggregate([{$group: {_id: "$order_id", total: {$sum: "$num"}}}])
注意:在使用$group的時候必須有一個_id作為分組的條件
#4.$sort
$sort的作用是用來進(jìn)行排序
db.order_item.aggregate([{$sort: {"price": -1}}])
注意: -1 表示降序跺讯, 1表示升序
#5.$limit
$limit的作用是限制顯示條數(shù)
db.order_item.aggregate([{$sort: {"price": -1}}, {$limit: 1}])
#6.$skip
$skip的作用是可以跳過的條數(shù)
db.order_item.aggregate([{$sort: {"price": -1}}, {$skip: 3}])
#7.$lookup
$lookup用來做關(guān)聯(lián)查詢枢贿,舉個例子:查詢order表中,order_id對應(yīng)的商品信息
db.order.aggregate([{$lookup:{from: "order_item", localField: "order_id", foreignField: "order_id"