《MongoDB入门教程》第22篇 聚合操作
Posted 不剪发的Tony老师
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了《MongoDB入门教程》第22篇 聚合操作相关的知识,希望对你有一定的参考价值。
本文将会介绍如何使用 MongoDB 聚合操作对文档进行分组,以及聚合表达式的使用。
聚合操作
MongoDB 聚合操作可以处理多个文档并返回计算后的结果。聚合操作通常用于按照指定字段的值进行分组并计算汇总结果。例如,聚合操作可以按照不同的产品计算订单中的总销售额。
聚合管道用于执行聚合操作,一个聚合管道包含一个或者多个处理文档的阶段。每个阶段都会基于它的输入文档执行操作,然后返回输出文档;输出文档会传递给下一个阶段,最后一个阶段返回最终的结果。
每个阶段的操作可以是以下内容之一:
- $project - 选择输出结果中包含的字段;
- $match - 选择要处理的文档;
- $limit - 限制传递到下一阶段的文档数量;
- $skip - 忽略指定数量的文档;
- $sort - 文档排序;
- $group - 文档分组;
- …
以下是定义聚合管道的语法:
db.collection.aggregate([ $match:...,$group:...,$sort:...]);
其中,
- aggregate() 方法用于指定聚合操作;
- 传递一个文档数组作为参数,每个文档描述了管道中的一个阶段。
MongoDB 4.2 及更高版本支持使用聚合管道更新文档。
聚合示例
首先,使用数据库 coffeeshop 存储咖啡的销量信息:
use coffeeshop
其次,为集合 sales 创建一些测试文档:
db.sales.insertMany([
"_id" : 1, "item" : "Americanos", "price" : 5, "size": "Short", "quantity" : 22, "date" : ISODate("2022-01-15T08:00:00Z") ,
"_id" : 2, "item" : "Cappuccino", "price" : 6, "size": "Short","quantity" : 12, "date" : ISODate("2022-01-16T09:00:00Z") ,
"_id" : 3, "item" : "Lattes", "price" : 15, "size": "Grande","quantity" : 25, "date" : ISODate("2022-01-16T09:05:00Z") ,
"_id" : 4, "item" : "Mochas", "price" : 25,"size": "Tall", "quantity" : 11, "date" : ISODate("2022-02-17T08:00:00Z") ,
"_id" : 5, "item" : "Americanos", "price" : 10, "size": "Grande","quantity" : 12, "date" : ISODate("2022-02-18T21:06:00Z") ,
"_id" : 6, "item" : "Cappuccino", "price" : 7, "size": "Tall","quantity" : 20, "date" : ISODate("2022-02-20T10:07:00Z") ,
"_id" : 7, "item" : "Lattes", "price" : 25,"size": "Tall", "quantity" : 30, "date" : ISODate("2022-02-21T10:08:00Z") ,
"_id" : 8, "item" : "Americanos", "price" : 10, "size": "Grande","quantity" : 21, "date" : ISODate("2022-02-22T14:09:00Z") ,
"_id" : 9, "item" : "Cappuccino", "price" : 10, "size": "Grande","quantity" : 17, "date" : ISODate("2022-02-23T14:09:00Z") ,
"_id" : 10, "item" : "Americanos", "price" : 8, "size": "Tall","quantity" : 15, "date" : ISODate("2022-02-25T14:09:00Z")
]);
然后,使用聚合管道查找“Americanos”品牌的咖啡的销量信息,按照杯型分组统计销量,最后按照销量总高到低进行排序:
db.sales.aggregate([
$match: item: "Americanos"
,
$group:
_id: "$size",
totalQty: $sum: "$quantity"
,
$sort: totalQty : -1
]);
返回结果如下:
[
_id: 'Grande', totalQty: 33 ,
_id: 'Short', totalQty: 22 ,
_id: 'Tall', totalQty: 15
]
示例中的聚合管道包含以下三个阶段:
- 阶段 1:$match 阶段过滤品牌为“Americanos”的咖啡,将结果传递给 $group 阶段;
- 阶段 2:$group 阶段按照咖啡杯型进行分组,使用 $sum 计算每个组的总销量。该阶段创建了一个新的文档集合,每个文档包含了 _id 和 totalQty 两个字段,然后将结果文档传递给 $sort 阶段;
- 阶段 3:$sort 阶段基于 totalQty 字段从大到小进行排序并返回结果文档。
SQL 与 MongoDB 聚合操作对比
以上聚合管道的等价 SQL 语句如下:
select
name as _id,
sum(quantity) as totalQty
from
sales
where name = 'Americanos'
group by name
order by totalQty desc;
下表列出了 SQL 和 MongoDB 聚合操作的比对:
SQL 子句 | MongoDB 聚合 |
---|---|
select | $project |
from | db.collection.aggregate(…) |
join | $unwind |
where | $match |
group by | $group |
聚合函数:avg、count、sum、max、min | 表达式:$avg、$count、$sum、$max、$min |
having | $match |
以上是关于《MongoDB入门教程》第22篇 聚合操作的主要内容,如果未能解决你的问题,请参考以下文章
《MongoDB入门教程》第26篇 聚合统计之$max/$min表达式
《MongoDB入门教程》第24篇 聚合统计之$count表达式
《MongoDB入门教程》第23篇 聚合统计之$sum表达式