聚合操作将多份文档分组,对每个分组做一系列操作然后得到一个值。mongodb有3种聚合方式:
集合流水线聚合
db.orders.aggregate([
{ $match: { status: "A" } },
{ $group: { _id: "$cust_id", total: { $sum: "$amount" } } }
])
操作分两步:
- 步骤一:
$match
阶段对文档的status
字段过滤,将status
="A" 的文档传递给下一步
. - 步骤二:
$group
阶段以cust_id 对文档分组,对每个
cust_id 计算 amount 总和
.
流水线
流水线表达式
- 指定了对文档的转换操作,格式详见: document
- 只能访问当前操作文档的数据,不能访问其他文档;是内存的转换
- 一般而言表达式是无状态的,除了: accumulator 表达式
- 在group 阶段用的accumulators 表达式在文档流经他们时会维持状态( totals, maximums, minimums……)
更多详见:Expressions
聚合流水线行为
mongodb 聚合 aggregate
是对整个数据集操作,可以用以下方法避免扫描整个数据集
流水线中的索引
提前过滤
当聚合只针对部分文档时,在聚合开头使用:
$match
, $limit
, $skip
流水线聚合更多详见:
- Aggregation Pipeline Optimization
- Aggregation Pipeline Limits
- Aggregation Pipeline and Sharded Collections
Map-Reduce 聚合
版本4.2加入,不建议对分片的数据集(sharded collection)做修改,以及非原子性的操作
MongoDB 对每份文档使用 map (满足 query 条件的文档). map 函数构造cust_id - amount 的键值对 . 对于有多个值的键, MongoDB 应用 reduce , 收集统计聚合的数据值. MongoDB 将结果存放到一个数据集中 . 或者,reduce的输出流经 finalize 函数做进一步的统计.
关于MapReduce 更多详见:
- Map-Reduce and Sharded Collections
- Map-Reduce Concurrency
- Map-Reduce Examples
- Perform Incremental Map-Reduce