【详细教程】一文参透 MongoDB 聚合查询

MongoDB 聚合查询

什么是聚合查询

聚合操作主要用于处理数据并返回计算结果。聚合操作将来自多个文档的值组合在一起,按条件分组后,再进行一系列操作(如求和、平均值、最大值、最小值)以返回单个结果。

MongoDB 的聚合查询

​ 聚合是 MongoDB 的高级查询语言,它允许我们通过转化合并由多个文档的数据来生成新的在单个文档里不存在的文档信息。MongoDB 中聚合 (aggregate) 主要用于处理数据(例如分组统计平均值、求和、最大值等),并返回计算后的数据结果,有点类似 sql 语句中的 count (*)、group by。

​ 在 MongoDB 中,有两种方式计算聚合:Pipeline 和 MapReduce。Pipeline 查询速度快于 MapReduce,但是 MapReduce 的强大之处在于能够在多台 Server 上并行执行复杂的聚合逻辑。MongoDB 不允许 Pipeline 的单个聚合操作占用过多的系统内存。

聚合管道方法

MongoDB 的聚合框架就是将文档输入处理管道,在管道内完成对文档的操作,最终将文档转换为聚合结果,MongoDB 的聚合管道将 MongoDB 文档在一个管道处理完毕后将结果传递给下一个管道处理,管道操作是可以重复的。

​ 最基本的管道阶段提供过滤器,其操作类似查询和文档转换,可以修改输出文档的形式。其他管道操作提供了按特定字段对文档进行分组和排序的工具,以及用于聚合数组内容(包括文档数组)的工具。

​ 此外,在管道阶段还可以使用运算符来执行诸如计算平均值或连接字符串之类的任务。聚合管道可以在分片集合上运行。

聚合流程

db.collection.aggregate () 是基于数据处理的聚合管道,每个文档通过一个由多个阶段(stage)组成的管道,可以对每个阶段的管道进行分组、过滤等功能,然后经过一系列的处理,输出相应的结果。

聚合管道方法的流程参见下图

上图的聚合操作相当于 MySQL 中的以下语句:

select cust_id as _id,sum(amount) as total from orders where status like "%A%" group by cust_id;

详细流程

  1. db.collection.aggregate() 可以用多个构件创建一个管道,对于一连串的文档进行处理。这些构件包括:筛选操作的 match、映射操作的 project、分组操作的 group、排序操作的 sort、限制操作的 limit、和跳过操作的 skip
  2. db.collection.aggregate() 使用了 MongoDB 内置的原生操作,聚合效率非常高,支持类似于 SQL Group By 操作的功能,而不再需要用户编写自定义的 JavaScript 例程。
  3. 每个阶段管道限制为 100MB 的内存。如果一个节点管道超过这个极限,MongoDB 将产生一个错误。为了能够在处理大型数据集,可以设置 allowDiskUse 为 true 来在聚合管道节点把数据写入临时文件。这样就可以解决 100MB 的内存的限制。
  4. db.collection.aggregate() 可以作用在分片集合,但结果不能输在分片集合,MapReduce 可以 作用在分片集合,结果也可以输在分片集合。
  5. db.collection.aggregate() 方法可以返回一个指针(cursor),数据放在内存中,直接操作。跟 Mongo shell 一样指针操作。
  6. db.collection.aggregate() 输出的结果只能保存在一个文档中,BSON Document 大小限制为 16M。可以通过返回指针解决,版本 2.6 中:DB.collect.aggregate() 方法返回一个指针,可以返回任何结果集的大小。

聚合语法

db.collection.aggregate(pipeline,options)

参数说明

参数 类型 描述
pipeline array 一系列数据聚合操作或阶段。详见聚合管道操作符 在版本 2.6 中更改:该方法仍然可以将流水线阶段作为单独的参数接受,而不是作为数组中的元素;但是,如果不将管道指定为数组,则不能指定 options 参数
options document 可选。 aggregate () 传递给聚合命令的其他选项。 2.6 版中的新增功能:仅当将管道指定为数组时才可用。

注意事项

​ 使用 db.collection.aggregate () 直接查询会提示错误,但是传一个空数组如 db.collection.aggregate ([]) 则不会报错,且会和 find 一样返回所有文档。

常用聚合管道

与 mysql 聚合类比

为了便于理解,先将常见的 mongo 的聚合操作和 mysql 的查询做下类比

SQL 操作 / 函数 mongodb 聚合操作
where $match
group by $group
having $match
select $project
order by $sort
limit $limit
sum() $sum
count() $sum
join $lookup

$count

返回包含输入到 stage 的文档的计数,理解为返回与表或视图的 find () 查询匹配的文档的计数。db.collection.count () 方法不执行 find () 操作,而是计数并返回与查询匹配的结果数。

语法

{ $count: <string> }

$count 阶段相当于下面 $group+$project 的序列:

db.collection.aggregate([
    {
        "$group": {
            "_id": null,"count": {// 这里count自定义,相当于mysql的select count(*) as tables
                "$sum": 1
            }
        }
    },{
        "$project": {// 返回不显示_id字段
            "_id": 0
        }
    }
])

示例

查询人数是 <

相关文章

文章浏览阅读552次。com.mongodb.MongoQueryException: Quer...
文章浏览阅读635次,点赞9次,收藏8次。MongoDB 是一种 NoSQ...
文章浏览阅读2.1k次。和。_mongodb 日期类型
文章浏览阅读1.7k次。Scalestack等客户期待使用MongoDB Atla...
文章浏览阅读970次。SpringBoot整合中间件mongodb、ES_sprin...
文章浏览阅读673次。MongoDB 简介_尚医通sql