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来可视化的编写复杂的聚合条件,并导出为相应编程语言的示例代码。