📣读完这篇文章里你能收获到
- MongoDB聚合框架的概念知识
- MongoDB的复杂聚合查询
- MQL与SQL的对比
- MQL聚合查询转换成相应语言的代码
MongoDB的聚合查询是比较复杂,不过别急着自我劝退,记得看到最后有
彩蛋
一、什么是 MongoDB 聚合框架(Aggregation Framework)
- MongoDB 聚合框架是一个计算框架,它可以:
- 作用在一个或几个集合上;
- 对集合中的数据进行的一系列运算;
- 将这些数据转化为期望的形式;
- 从效果而言,聚合框架相当于 SQL 查询中的:
- GROUP BY
- LEFT OUTER JOIN
- AS等
二、聚合框架中的管道(Pipeline)和步骤(Stage)
- 整个聚合运算过程称为管道(
Pipeline
),它是由多个步骤(Stage
)组成的,每个管道:
- 接受一系列文档(
原始数据
); - 每个步骤对这些文档进行一系列
运算
; - 结果文档输出给下一个
步骤
;
三、聚合运算的基本格式
pipeline = [$stage1, $stagde2, ...$stageN];
db.<COLLECTION>.aggregate
( pipeline,
{ options }
);
常见步骤
常见步骤中的运算符
四、MQL常用聚合查询与SQL对比
案例1—分页查询
- SQL
SELECT
FIRST_NAME AS `名`, LAST_NAME AS `姓`
FROM Users
WHERE GENDER = '男'
SKIP 100
LIMIT 20
- MQL
db.users.aggregate([
{$match: {gender: ’’男”}},
{$skip: 100},
{$limit: 20},
{$project: {
'名': '$first_name',
'姓': '$last_name'
}}
]);
案例2—GroupBy分组查询
- SQL
SELECT DEPARTMENT, COUNT(NULL) AS EMP_QTY
FROM Users
WHERE GENDER = '女'
GROUP BY DEPARTMENT HAVING
COUNT(*) < 10
- MQL
db.users.aggregate([
{$match: {gender: '女'}},
{$group: {
_id: '$DEPARTMENT’,
emp_qty: {$sum: 1}
}},
{$match: {emp_qty: {$lt: 10}}}
]);
五、MQL特有的聚合查询
$unwind
> db.students.findOne()
{
name:'张三',
score:[
{subject:'语文',score:84},
{subject:'数学',score:90},
{subject:'外语',score:69}
]
}
> db.students.aggregate([{$unwind: '$score'}])
{name: '张三', score: {subject: '语文', score: 84}}
{name: '张三', score: {subject: '数学', score: 90}}
{name: '张三', score: {subject: '外语', score: 69}}
$bucket
db.products.aggregate([{
$bucket:{
groupBy: "$price", boundaries: [0,10,20,30,40],
default: "Other",
output:{"count":{$sum:1}}
}
}])
$facet
db.products.aggregate([{
$facet:{
price:{
$bucket:{…}
},
year:{
$bucket:{…}
}
}
}])
六、聚合查询实验
数据准备
- 这部分数据需要原始数据的私聊我拿
聚合实验一:计算总销量
- 计算到目前为止的所有订单的总销售额
db.orders.aggregate([
{ $group:
{
_id: null,//_id为null,表示不进行分组
total: { $sum: "$total" }
}
}
])
// 结果: // { "_id" : null, "total" : NumberDecimal("44019609") }
聚合实验二:订单金额按日期汇总
- 查询2019年第一季度(1月1日~3月31日)已完成订单(completed)的订单总金额和订单总数
db.orders.aggregate([
// 步骤一:匹配条件,相当于sql中的where
{ $match: { status: "completed", orderDate: {
$gte: ISODate("2019-01-01"),//MongoDB中日期均需要通过ISODate进行转换
$lt: ISODate("2019-04-01") }
} },
// 步骤二:聚合订单总金额、总运费、总数量
{ $group: {
_id: null,
total: { $sum: "$total" },
shippingFee: { $sum: "$shippingFee" },
count: { $sum: 1 }
} },
// 步骤三:投影及汇总金额+运费
{ $project: {//$project相当sql中select x1 as s1
// 计算总金额
grandTotal: { $add: ["$total", "$shippingFee"] },
count: 1,//1表示显示,0则为不显示
_id: 0 } }
])
// 结果:
// { "count" : 5875, "grandTotal" : NumberDecimal("2636376.00") }
七、彩蛋
- 通过
Mongo Compass
来创建复杂的聚合计算管道
手把手教学
以上一章节的聚合实验二为例进行讲解:订单金额按日期汇总
- 步骤一:匹配条件
筛选match
stage,右边会跟据你的条件给你筛选出部分实时数据,随后进行下一个stage的输入,点击ADD STAGE
- 步骤二:聚合订单总金额、总运费、总数量
- 步骤三:投影及汇总金额+运费