聚合管道是mongodb的重要特性和功能之一,通过聚合管道可以且不仅限于实现关联查询、汇总、分组、统计等高级应用。下面的内容根据mongodb官方文档翻译整理而来,供速查。水平有限,难免有误,不足之处恳请批评指正。
集合聚合db.collection.aggregate
db.collection.aggregate方法中,管道的阶段是个数组,每个数组元素是一个阶段。文档通过每个阶段进行处理后输出。除了$out
、$merge
和$geoNear
外,其他阶段可以在管道中出现多次。
阶段 | 描述 |
---|---|
$addField | 给文档中添加一个字段,跟$project 类似,$addField会重塑流中文档,输出字段包括新添加的字段和原有的全部字段 |
$bucket | 根据表达式和边界,对输入文档进行分类(分组),得到一组新的文档,称为bucket桶。 |
$bucketAuto | 根据表达式对输入文档进行分类(分组),自动确定每个桶的边界,尽可能的把文档平均分配到每个桶。 |
$changestream | 返回一个集合、数据库或整个集群上的变化流游标。必须作为聚合管道的第一阶段使用。当数据变化时,使用next移动光标会返回变化相关的数据。 |
$collStats | 返回一个集合或者视图的统计信息,只能在聚合管道的第一个阶段使用。 |
$count | 返回管道中当前阶段的文档数量。这个跟聚合中的累加器不一样 |
$densify | 以字段值为序列,为缺失的值创建新文档 |
documents | 根据给定的内容返回一个文档 |
$facet | 在一个阶段内,对输入文档执行多个维度(方面)的聚合,输出文档的每个子聚合都有其自己的字段,并且子聚合文档以数组的方式进行排序。 |
$fill | 填充文档中缺失或为空的值。 |
$geoNear | 根据与地理空间点的远近,返回一个有序的文件流。融合了$match、$sort 和$limit 等地理空间数据的功能。输出的文档包括一个额外的距离字段,并且可以包含一个位置标识符字段。 |
$graphLookup | 对集合执行递归搜索,并为每个输出文档增加一个数组字段,该字段包含了遍历结果。 |
$group | 根据表达式对文档进行分组并汇总(如果指定),每个不同的分组输出一个文档,如果不指定汇总,文档只包含标识符字段。 |
$indexStats | 返回集合使用到的全部索引的统计信息 |
$limit | 输出指定的前n个文档,对所有输入的文档来说,只有前n个文档才会被输出。 |
$listSessions | 列出system.sessions集合中的会话,有些临时会话生存时间比较短,不一定会被system.sessions记录到 |
$lookup | 左外连接一个集合(同一个库),对连接的集合的文档进行筛选处理。 |
$match | 对输入的文档进行筛选,只有符合条件的文档可以进入到下个阶段。$match 使用标准的MongoDB查询。 |
$merge | 把聚合管道的执行结果写到一个集合,该阶段可以把结果(插入新文档、合并文档、替换文档、保持已存在的文档、失败的操作、自定义管道更新文档)合并到集合。$meger 阶段只能用于管道的最后一个阶段。 |
$out | 也是把聚合管道的执行结果写到一个集合,功能没有$merge 那么多。 |
$planCacheStats | 返回执行计划的缓存信息 |
$project | 对管道中的文档进行重塑,比如增加或删除字段 |
$redact | 根据文档自身信息对文档进行重塑,整合了$project 和$match 的功能,可以实现字段级的重塑。应用于输入、输出和零文档。 |
$replaceRoot | 使用内嵌文档对字段进行替换,这个操作可以替换所有已存在字段,包括_id字段。将输入文档的内嵌文档提升到顶层。它还有个别名$replaceWith |
$replaceWith | 跟$replaceRoot 功能一样,互为别名。 |
$sample | 随机选择指定数量的文档 |
$search | 对指定的字段们执行一个全文检索,但是这些字段必须能被Atlas Search索引覆盖。注意啊:$search 只能用于MongoDB Atlas集群,不能用于自管理的部署 |
$searchMeta | 返回MongoDB Atlas查询文档的元数据信息(比如字段类型之类的),这个也只能用于MongoDB Atlas集群 |
$set | 为文档添加新字段,跟$project 类似,$set 可以重塑管道中的文档,输出的字段包括添加的字段和原有的字段。它还有个别名$addFields 。 |
$setWindowFields | 把文档分组到窗口,并使用指定的运算符对这些窗口进行操作。窗口其实就是集合中指定的文档范围。 |
$skip | 跳过前n个文档,n为指定要跳过的文档数量。 |
$sort | 按照指定的键对文档进行重新排序,不会改变文档内容 |
$sortByCount | 基于指定表达式的值对文档进行分组然后统计每个分组内的文档数量,并按照文档数量排序 |
$unionWith | 把两个集合进行并集操作,跟Sql的union类似。 |
$unset | 从文档中移除字段,$unset 是$project 移除字段的别名 |
$unwind | 解构文档中的字段,为数组的每个元素输出一个文档。每个输出文档使用一个数组元素。对于每个输入文档,输出n个文档,其中n是数组元素的数量,空数组可以为零。 |
库聚合 db.aggregate
下面是可以用于db.aggregate的阶段
阶段 | 描述 |
---|---|
$changeStream | 返回一个集合Change Stream的光标,这个阶段在管道中只能作为第一个阶段使用一次。 |
$currentOp | 返回MongoDB正在运行及休眠操作的信息。 |
$listLocalSessions | 列出所有近期连接到mongos或mongod实例的活动会话,有些会话可能还没有记录到system.session集合中。 |
$documents | 根据输入的值返回文档,相当于返回常量的文档,支持部分系统变量(比如:$$NOW 、$$SEARCH_META )或表达式(比如:$let 、$lookup 。 |
可用聚合管道更新的命令
下面的两个命令可以使用聚合管道作为更新的输入
命令 | mongosh方法 |
---|---|
findAndModify | db.collection.findOneAndUpdate() db.collection.findAndMondify() |
update | db.collection.updateOne() db.collection.updateMany() Bulk.find.update() Bulk.find.updateOne() Bulk.find.upsert() |
总结
平时做项目比较常用到的还是汇总查询相关的一些阶段,比如进行数据筛选的$match
、$search
,进行表连接的$lookup
,进行分组汇总的$group
,进行文档重塑的$project
、$replaceRoot
,限制文档数量的$limit、$skip
,排序用的$sort
等。这里只是简单给出一个快速参考,具体的命令可以进一步查阅Mongodb文档。