MongoDB Aggregation(聚合)的总体认知

MongoDB 聚合

聚合操作处理多个文档并返回计算结果。可以使用聚合操作的情形:

  • 将多个文档中的值分组在一起。
  • 对分组的数据执行操作以返回单个结果。
  • 分析数据随时间的变化。

要执行聚合操作,MongoDB可以使用:

  • 聚合管道 Aggregation pipelines
  • 单一目的聚合方法 Single purpose aggregation methods
  • 使用映射-规约模式功能 Map-reduce functions

聚合管道 Aggregation pipelines

简介:聚合管道由处理文档的一个或多个阶段组成,每个阶段对输入文档执行一个操作。例如,stage可以过滤文档、分组文档和计算值。从一个阶段输出的文档将被输入到下一个阶段。聚合管道可以为文档组返回结果。例如,返回总数、平均值、最大值和最小值。

语法db.collection.aggregate( [ { }, ... ] )

聚合管道阶段

管道阶段 描述
$addFields 向文档中添加新字段。类似于$project$addFields重塑流中的每个文档;具体来说,通过向包含输入文档的现有字段和新添加字段的输出文档添加新字段。`` s e t ‘ 是 ‘ set`是` setaddFields`的别名。
$bucket 根据指定的表达式和存储桶边界将进入的文档分类到称为存储桶的组中。
$bucketAuto 根据指定的表达式将传入的文档分类为特定数量的组,称为桶。为了将文档均匀地分布到指定数量的桶中,将自动确定桶边界。
$collStats 返回关于集合或视图的统计信息。
$count 返回聚合管道在此阶段的文档数量的计数。
$facet 在同一组输入文档的单个阶段中处理多个聚合管道。支持创建能够在单个阶段中跨多个维度或方面描述数据的多面聚合。
$geoNear 根据地理空间点的邻近性返回有序的文档流。合并地理空间数据的$match$sort$limit功能。输出文档包括一个额外的距离字段,并且可以包括一个位置标识符字段。
$graphLookup 对集合执行递归搜索。向每个输出文档添加一个新的数组字段,该字段包含该文档的递归搜索的遍历结果。
$group 按指定的标识符表达式对输入文档进行分组,并将累加器表达式(如果指定)应用到每个组。使用所有输入文档,并为每个不同的组输出一个文档。输出文档只包含标识符字段,如果指定,则包含累积字段。
$indexStats 返回关于集合每个索引使用情况的统计信息。
$limit 将前n个文档未修改地传递到管道中,其中n是指定的限制。对于每个输入文档,输出一个文档(对于前n个文档)或0个文档(在前n个文档之后)。
$listSessions 执行左外连接到同一数据库中的另一个集合,以从“连接的”集合中筛选文档进行处理。
$match 筛选文档流,只允许匹配的文档未经修改地传递到下一个管道阶段。$match使用标准MongoDB查询。对于每个输入文档,输出一个文档(匹配)或零个文档(不匹配)。
$merge 4.2新版功能。将聚合管道的结果文档写入集合。该阶段可以将结果合并(插入新文档、合并文档、替换文档、保留现有文档、操作失败、使用自定义更新管道处理文档)到输出集合中。要使用$merge阶段,它必须是管道中的最后一个阶段。
$out 将聚合管道的结果文档写入集合。要使用$out阶段,它必须是管道中的最后一个阶段。
$planCacheStats 返回集合的计划缓存信息。
$project 重塑流中的每个文档,例如添加新字段或删除现有字段。对于每个输入文档,输出一个文档。
$redact 根据存储在文档本身中的信息限制每个文档的内容,从而重塑流中的每个文档。合并$project$match的功能。可用于实现字段级别的编校。对于每个输入文档,输出一个或零个文档。
$replaceRoot 用指定的嵌入文档替换文档。该操作将替换输入文档中的所有现有字段,包括_id字段。指定嵌入在输入文档中的文档,以将嵌入的文档提升到最高级别。$replaceWith$replaceRoot阶段的别名
$replaceWith 用指定的嵌入文档替换文档。该操作将替换输入文档中的所有现有字段,包括_id字段。指定嵌入在输入文档中的文档,以将嵌入的文档提升到最高级别。
$sample 从其输入中随机选择指定数量的文档。
$search 对Atlas集合中的一个或多个字段执行全文搜索。
$set 向文档中添加新字段。类似于$project$set重塑流中的每个文档;具体来说,通过向包含输入文档的现有字段和新添加字段的输出文档添加新字段。 $set是``$addFields`阶段的别名。
$setWindowFields 5.0新版功能。将文档分组到窗口中,并对每个窗口中的文档应用一个或多个操作符。
$skip 跳过前n个文档,其中n是指定的跳过数,并将其余未修改的文档传递给管道。对于每个输入文档,输出0个文档(对于前n个文档)或1个文档(如果在前n个文档之后)。
$sort 按指定的排序键对文档流重新排序。只有顺序发生了变化;这些文件没有被修改。对于每个输入文档,输出一个文档。
$sortByCount 根据指定表达式的值对传入文档进行分组,然后计算每个不同组中的文档计数。
$unionWith 4.4新版功能。执行两个集合的并集;I.e.将两个集合的管道结果合并为一个结果集。
$unset 从文档中移除/排除字段。$unset$project的别名,用于删除字段。
$unwind 从输入文档中解构数组字段,为每个元素输出文档。每个输出文档都将数组替换为一个元素值。对于每个输入文档,输出n个文档,其中n是数组元素的数量,对于空数组可以为零。

注意点

  • 除了$out$merge$geoNear stage外,所有stage都可以在管道中多次出现

单一目的聚合方法

简介:MongoDB提供了单一目的聚合方法用于将来自单个集合的文档聚合在一起。虽然这些操作提供了对常见聚合流程的简单访问,但它们缺乏聚合管道的灵活性和功能。

例如:db.collection.estimatedDocumentCount(), db.collection.count(), db.collection.distinct()。

基本操作

# 插入测试数据
db.col01.insertMany(
[
    {name:'doc01',age:12,status:'open',permissions:['insert'],son:{name:'a', age:11}, createTime: new Date()}, 
    {name:'doc02',age:23,status:'open',permissions:['insert'],son:{name:'b', age:12}, createTime: new Date()},
    {name:'doc02',age:34,status:'open',permissions:['insert'],son:{name:'c'}, createTime: new Date()},
    {name:'doc03',age:56,status:'open',permissions:['insert'],son:{name:'d', age:13}, createTime: new Date()},
    {name:'doc03',age:67,status:'open',permissions:['insert'],son:{name:'e'}, createTime: new Date()},
    {name:'doc04',age:78,status:'close',permissions:['insert'],son:{name:'f', age:14}, createTime: new Date()},
    {name:'doc05',age:89,status:'close',permissions:['insert'],son:{name:'g'}, createTime: new Date()}
]
, {})

# 计数
mymongo>  db.col01.count()
DeprecationWarning: Collection.count() is deprecated. Use countDocuments or estimatedDocumentCount.
7
mymongo>  db.col01.countDocuments()
7
mymongo>  db.col01.estimatedDocumentCount()
7

# 对name进行去重
mymongo>  db.col01.distinct("name")
[ 'doc01', 'doc02', 'doc03', 'doc04', 'doc05' ]

使用映射-规约模式功能 map-reduce

简介:从MongoDB 5.0开始,已经弃用了map-reduce操作。聚合管道提供了比映射-减少操作更好的性能和可用性。可以使用聚合管道操作符(如 g r o u p 、 group、 groupmerge等)重写Map-reduce操作。

你可能感兴趣的:(mongodb,mongodb)