MongoDB聚合操作
MongoDB聚合框架(Aggregation Framework)是一个计算框架,它可以:
作用在一个或几个集合上;
对集合中的数据进行一系列的运算
将这些数据转化为期望的形式
从效果而言,聚合框架相当于sql查询中的:
GROUP BY
LEFT OUTER JOIN
AS等
管道(Pipeline)和步骤(Stage)
整个聚合运算过程称为管道(Pipeline),它是由多个步骤(Stage)组成的,
每个管道:
- 接受一系列文档(原始数据)
- 每个步骤对这些文档进行一系列运算
- 结果文档输出给下一个步骤

聚合运算的基本格式
pipeline = [$stage1, $stage2, ...stageN] // 一系列的计算步骤,每个stage是一个json格式
db.<COLLECTION>.aggregate(
pipeline,
{ options }
);
常见步骤
mongo的每个关键词都有一个$符号作为前缀


常见步骤中的运算符

聚合运算的使用场景
聚合查询可以用于OLAP和OLTP场景,例如:

MQL常用步骤与SQL对比
1. 根据性别查询,跳过100行后,只取20个数据,并对姓名做映射
pipline = [
{$match:{gender:"男"}},
{$skip:100},
{$limit:20},
{$project:{
'名':'$first_name',
'姓':'$last_name'
}}
];
db.user.aggregate(pipline);
2.按照部门查找女性员工小于10人的个数

pipeline=[
{$match:{gender:'女'}},
{$group:{
_id:'$DEPARTMENT', // 必须使用_id
emp_qty:{$sum:1} // $sum求和,每次遇到该department就加1
}},
{$match:{emp_qty:{$lt:10}}}
];
db.user.aggregate(pipeline);
3.mql特有步骤$unwind,把数组展开
db.students.aggregate([{$unwind:'$score'}])
将score数组展开


4.mql特有步骤$bucket,自动把数值进行分组,放到各个组里
groupBy:按照哪个字段进行分组,
boundaries:指定分桶的范围
output:输出每个分桶的个数

4.mql特有步骤$bucket,把不同bucket组合起来

聚合查询实践
数据模型
{
"_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")
}
总销量
计算到目前为止所有订单的总销售额
_id 指定要进行分组的字段
result = orders_collection.aggregate([{
"$group": {
"_id": 'null',
"total": {"$sum": "$total"}
}
}])
订单金额汇总
查询2019年第一季度(1月1日~3月31日)已完成订单(completed)的订单总金额和订单总数
from_date = datetime.strptime('2019-01-01', '%Y-%m-%d')
to_date = datetime.strptime('2019-04-01', '%Y-%m-%d')
result1 = orders_collection.aggregate([
{
"$match": {
"status": "completed",
"orderDate": {
"$gte": from_date,
"$lt": to_date
}
}
},
{
"$group": {
"_id": 'null',
"total": {"$sum": "$total"},
"shippingFee": {"$sum": "$shippingFee"},
"count": {"$sum": 1}
}
},
{
"$project": {
"grandTotal": {
"$add": ["$total", "$shippingFee"]
},
"count": 1,
"_id": 0
}
}
])
for r in result1:
print(r)
注意在python中不同的操作中的是否需要按照字符串来处理。
当然也可以用mongodb-compass来可视化的编写复杂的聚合条件,并导出为相应编程语言的示例代码。
浙公网安备 33010602011771号