【Mongodb】聚合運算
阿新 • • 發佈:2020-06-28
Mongodb高手課筆記
聚合查詢
Mongodb可以進行一系列的聚合查詢,從而計算出使用者需要的結果
整個聚合運算的過程稱為管道Pipeline
,它是由多個步驟stage
組成的.就像是過濾器,經過每多次過濾得到計算結果.
聚合運算的基本格式
pipeline = [$stage1, $stage2, ...$stageN];
db.<COLLECTION>.aggregate(
pipeline,
{ options }
);
常見步驟:
步驟 | 作用 | SQL等價運算子 |
---|---|---|
$match | 過濾 | WHERE |
$project | 投影 | AS |
$sort | 排序 | ORDER BY |
$group | 分組 | GROUP BY |
$skip $limit | 結果限制 | SKIP/LIMIT |
$lookup | 左外連線 | LEFT OUTER JOIN |
$unwind | 展開陣列 | N/A |
$graphLookup | 圖搜尋 | N/A |
$facet $bucket | 分面搜尋 | N/A |
常見步驟中的運算子:
$match •$eq $gt $gte $lt $lte •$and $or $not $in •$geoWithin $intersect $project •選擇需要的或排除不需要的欄位 • $map $reduce $filter •$range •$multiply $divide $substract $add •$year $month $dayOfMonth $hour $minute $second $group •$sum $avg •$push $addToSet •$first $last $max $min
MQL 常用步驟與 SQL 對比
SELECT
FIRST_NAME AS `名`,
LAST_NAME AS `姓`
FROM Users
WHERE GENDER = '男'
SKIP 100
LIMIT 20
db.users.aggregate([
{$match: {gender: ’’男”}},
{$skip: 100},
{$limit: 20},
{$project: {
'名': '$first_name',
'姓': '$last_name'
}}
]);
SELECT DEPARTMENT, COUNT(NULL) AS EMP_QTY FROM Users WHERE GENDER = '女' GROUP BY DEPARTMENT HAVING COUNT(*) < 10
db.users.aggregate([
{$match: {gender: '女'}},
{$group: {
_id: '$DEPARTMENT',
emp_qty: {$sum: 1}
}},
{$match: {emp_qty: {$lt: 10}}}
]
MQL 特有步驟
$unwind
如查詢出一條訂單記錄
db.orders.findOne();
{
"_id" : ObjectId("5dbe7a545368f69de2b4d36e"),
"street" : "493 Hilll Curve",
"city" : "Champlinberg",
"state" : "Texas",
"country" : "Malaysia",
"zip" : "24344-1715",
"phone" : "425.956.7743 x4621",
"name" : "Destinee Schneider",
"userId" : 3573,
"orderDate" : ISODate("2019-03-26T03:20:08.805Z"),
"status" : "created",
"shippingFee" : NumberDecimal("8.00"),
"orderLines" : [
{
"product" : "Refined Fresh Tuna",
"sku" : "2057",
"qty" : 25,
"price" : NumberDecimal("56.00"),
"cost" : NumberDecimal("46.48")
},
{
"product" : "Refined Concrete Ball",
"sku" : "1738",
"qty" : 61,
"price" : NumberDecimal("47.00"),
"cost" : NumberDecimal("47")
},
{
"product" : "Rustic Granite Towels",
"sku" : "500",
"qty" : 62,
"price" : NumberDecimal("74.00"),
"cost" : NumberDecimal("62.16")
},
{
"product" : "Refined Rubber Salad",
"sku" : "1400",
"qty" : 73,
"price" : NumberDecimal("93.00"),
"cost" : NumberDecimal("87.42")
},
{
"product" : "Intelligent Wooden Towels",
"sku" : "5674",
"qty" : 72,
"price" : NumberDecimal("84.00"),
"cost" : NumberDecimal("68.88")
},
{
"product" : "Refined Steel Bacon",
"sku" : "5009",
"qty" : 8,
"price" : NumberDecimal("53.00"),
"cost" : NumberDecimal("50.35")
}
],
"total" : NumberDecimal("407")
}
如果使用$unwind,可以把Bson資料裡面的陣列展開,這個功能是不是很強大呢,可以用來做報表之類的
db.orders.aggregate([{$limit: 1},{ $unwind: "$orderLines"}]);
結果
{ "_id" : ObjectId("5dbe7a545368f69de2b4d36e"), "street" : "493 Hilll Curve", "city" : "Champlinberg", "state" : "Texas", "country" : "Malaysia", "zip" : "24344-1715", "phone" : "425.956.7743 x4621", "name" : "Destinee Schneider", "userId" : 3573, "orderDate" : ISODate("2019-03-26T03:20:08.805Z"), "status" : "created", "shippingFee" : NumberDecimal("8.00"), "orderLines" : { "product" : "Refined Fresh Tuna", "sku" : "2057", "qty" : 25, "price" : NumberDecimal("56.00"), "cost" : NumberDecimal("46.48") }, "total" : NumberDecimal("407") }
{ "_id" : ObjectId("5dbe7a545368f69de2b4d36e"), "street" : "493 Hilll Curve", "city" : "Champlinberg", "state" : "Texas", "country" : "Malaysia", "zip" : "24344-1715", "phone" : "425.956.7743 x4621", "name" : "Destinee Schneider", "userId" : 3573, "orderDate" : ISODate("2019-03-26T03:20:08.805Z"), "status" : "created", "shippingFee" : NumberDecimal("8.00"), "orderLines" : { "product" : "Refined Concrete Ball", "sku" : "1738", "qty" : 61, "price" : NumberDecimal("47.00"), "cost" : NumberDecimal("47") }, "total" : NumberDecimal("407") }
{ "_id" : ObjectId("5dbe7a545368f69de2b4d36e"), "street" : "493 Hilll Curve", "city" : "Champlinberg", "state" : "Texas", "country" : "Malaysia", "zip" : "24344-1715", "phone" : "425.956.7743 x4621", "name" : "Destinee Schneider", "userId" : 3573, "orderDate" : ISODate("2019-03-26T03:20:08.805Z"), "status" : "created", "shippingFee" : NumberDecimal("8.00"), "orderLines" : { "product" : "Rustic Granite Towels", "sku" : "500", "qty" : 62, "price" : NumberDecimal("74.00"), "cost" : NumberDecimal("62.16") }, "total" : NumberDecimal("407") }
{ "_id" : ObjectId("5dbe7a545368f69de2b4d36e"), "street" : "493 Hilll Curve", "city" : "Champlinberg", "state" : "Texas", "country" : "Malaysia", "zip" : "24344-1715", "phone" : "425.956.7743 x4621", "name" : "Destinee Schneider", "userId" : 3573, "orderDate" : ISODate("2019-03-26T03:20:08.805Z"), "status" : "created", "shippingFee" : NumberDecimal("8.00"), "orderLines" : { "product" : "Refined Rubber Salad", "sku" : "1400", "qty" : 73, "price" : NumberDecimal("93.00"), "cost" : NumberDecimal("87.42") }, "total" : NumberDecimal("407") }
{ "_id" : ObjectId("5dbe7a545368f69de2b4d36e"), "street" : "493 Hilll Curve", "city" : "Champlinberg", "state" : "Texas", "country" : "Malaysia", "zip" : "24344-1715", "phone" : "425.956.7743 x4621", "name" : "Destinee Schneider", "userId" : 3573, "orderDate" : ISODate("2019-03-26T03:20:08.805Z"), "status" : "created", "shippingFee" : NumberDecimal("8.00"), "orderLines" : { "product" : "Intelligent Wooden Towels", "sku" : "5674", "qty" : 72, "price" : NumberDecimal("84.00"), "cost" : NumberDecimal("68.88") }, "total" : NumberDecimal("407") }
{ "_id" : ObjectId("5dbe7a545368f69de2b4d36e"), "street" : "493 Hilll Curve", "city" : "Champlinberg", "state" : "Texas", "country" : "Malaysia", "zip" : "24344-1715", "phone" : "425.956.7743 x4621", "name" : "Destinee Schneider", "userId" : 3573, "orderDate" : ISODate("2019-03-26T03:20:08.805Z"), "status" : "created", "shippingFee" : NumberDecimal("8.00"), "orderLines" : { "product" : "Refined Steel Bacon", "sku" : "5009", "qty" : 8, "price" : NumberDecimal("53.00"), "cost" : NumberDecimal("50.35") }, "total" : NumberDecimal("407") }
$bucket
$bucket可以用來做目錄,比如淘寶篩選欄裡面會有價格區間
db.products.aggregate([{
$bucket:{
groupBy: "$price",
boundaries: [0,10,20,30,40],
default: "Other",
output:{"count":{$sum:1}}
}
}])
db.products.aggregate([{
$facet:{
price:{
$bucket:{…}
},
year:{
$bucket:{…}
}
}
}])