MongoDB聚合管道操作详解(附带实例)
聚合操作主要用于处理数据并返回计算结果。聚合操作将来自多个文档的值组合在一起,按条件分组后,再进行一系列操作(如求和、计算平均值、计算最大值、计算最小值)以返回单个结果。
MongoDB 提供了 3 种执行聚合的操作,分别是聚合管道、map-reduce和单一目标聚合,接下来重点介绍聚合管道操作。
MongoDB 的聚合管道操作就是将文档输入处理管道,在管道内完成对文档的操作,最终将文档转换为聚合结果。
最基本的管道阶段提供过滤器,过滤器操作类似查询和文档转换,可以修改输出文档的形式。其他管道操作提供按特定字段对文档进行分组和排序的工具,以及用于聚合数组内容(包括文档数组)的工具。此外,管道阶段还可以使用运算符来执行诸如计算平均值或连接字符串之类的任务。聚合管道可以在分片集合上运行。
聚合管道操作的流程如下图所示:

图 1 聚合管道操作流程
图 1 所示的聚合管道操作相当于 MySQL 中的以下语句:
聚合管道操作的语法比较难理解,下面给出一个示例,和 MySQL 进行对照。示例的代码如下:
这段代码相当于 MySQL 中的以下代码:
再举一个复杂的例子,按照指定条件先对文档进行过滤,然后对满足条件的文档数量进行统计,最后将统计结果输出到临时文件中。首先插入多条文档,代码如下:
然后使用聚合管道操作对文档数量进行统计,代码如下:
MongoDB 提供了 3 种执行聚合的操作,分别是聚合管道、map-reduce和单一目标聚合,接下来重点介绍聚合管道操作。
MongoDB 的聚合管道操作就是将文档输入处理管道,在管道内完成对文档的操作,最终将文档转换为聚合结果。
最基本的管道阶段提供过滤器,过滤器操作类似查询和文档转换,可以修改输出文档的形式。其他管道操作提供按特定字段对文档进行分组和排序的工具,以及用于聚合数组内容(包括文档数组)的工具。此外,管道阶段还可以使用运算符来执行诸如计算平均值或连接字符串之类的任务。聚合管道可以在分片集合上运行。
聚合管道操作的流程如下图所示:

图 1 聚合管道操作流程
图 1 所示的聚合管道操作相当于 MySQL 中的以下语句:
select cust_id as _id,sum(amount) as total from orders where status like "%A%" group by cust_id; MongoDB 中聚合管道操作的语法如下: db.collection.aggregate([ { $match: {< query >} }, } { $group: {< field1 >:< field2 >} } ])上述代码中各参数的含义如下:
- query 参数设置统计查询条件,这类似于 SQL 的 where 语句的功能;
- field1 参数为分类字段,要求使用 _id 表示分类字段;
- field2 参数为包含各种统计操作符的数字型字段,如 $sum、$avg、$min 等。
聚合管道操作的语法比较难理解,下面给出一个示例,和 MySQL 进行对照。示例的代码如下:
db.mycol.aggregate([ { $group: {_id: "$by_user", num_tutorial: {$sum: 1}} } ])
这段代码相当于 MySQL 中的以下代码:
select by_user as _id, count(*) as num_tutorial from mycol group by by_user;
再举一个复杂的例子,按照指定条件先对文档进行过滤,然后对满足条件的文档数量进行统计,最后将统计结果输出到临时文件中。首先插入多条文档,代码如下:
db.articles.insert([ { "_id": 10, "author": "dave", "score": 80, "views": 100 }, { "_id": 11, "author": "dave", "score": 85, "views": 521 }, { "_id": 12, "author": "ahn", "score": 60, "views": 1000 }, { "_id": 13, "author": "li", "score": 55, "views": 5000 }, { "_id": 14, "author": "annT", "score": 60, "views": 50 }, { "_id": 15, "author": "li", "score": 94, "views": 999 }, { "_id": 16, "author": "ty", "score": 95, "views": 1000 } ]);
然后使用聚合管道操作对文档数量进行统计,代码如下:
db.articles.aggregate([ { $match: { $or: [ { score: { $gt: 70, $lt: 90 } }, { views: { $gte: 1000 } } ] } }, { $group: { _id: null, count: { $sum: 1 } } } ]);管道阶段的 RAM 限制为 100MB。若要允许处理大型数据集,则可使用 allowDiskUse 选项启用聚合管道操作阶段,将数据写入临时文件。