《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
fromdb.collection.aggregate(…)
join$unwind
where$match
group by$group
聚合函数:avg、count、sum、max、min表达式:$avg、$count、$sum、$max、$min
having$match

以上是关于《MongoDB入门教程》第22篇 聚合操作的主要内容,如果未能解决你的问题,请参考以下文章

《MongoDB入门教程》第22篇 聚合操作

《MongoDB入门教程》第26篇 聚合统计之$max/$min表达式

《MongoDB入门教程》第24篇 聚合统计之$count表达式

《MongoDB入门教程》第23篇 聚合统计之$sum表达式

《MongoDB入门教程》第23篇 聚合统计之$sum表达式

《MongoDB入门教程》第25篇 聚合统计之$avg表达式