什么是管道?
了解Linux的同学应该不陌生,管道是将上一条命令产生的结果作为下一条命令的输入,用”|“表示。
而在MongoDB中也有类似的概念,它的全称是”聚合管道(Aggregate Pipeline)“,异曲同工。
相关概念
为了清晰的阐述管道的概念,需要先明确一些相关概念。
aggregate
表示聚合管道
阶段(stage)
一个aggregate由多个阶段组成。上一阶段产生的结果会作为下一阶段的输入,所以也会被形象的称为流水线(Pipeline)。
看一个官网的例子:
db.orders.aggregate([
{ $match: { status: "A" } },
{ $group: { _id: "$cust_id", total: { $sum: "$amount" } } }
])
stage 1:通过match命令筛选出目标文档。
stage 2: 然后将筛选出来的文档再通过group命令进行分组,最后通过sum命令对分组后的数据进行累加操作。
管道表达式
这个概念相对复杂,以下仅为个人理解。
- 如果理解编程中“表达式”的概念,所谓“管道表达式”也是异曲同工,就是对文档中的数据的状态做一些转换的公式。
- 管道表达式只能对管道中当前文档进行操作,并且不能引用其他文档中的数据。
- 表达式操作都是内存存储的。
- 表达式是无状态的,只有在聚合时才进行真正的计算。仅有一处例外:累加器表达式 $sum。
- 表达式是幂等的,在入参相同的情况下,无论计算多少次,返回的结果必然一致。
聚合管道行为
在MongoDB中,管道命令在单个集合上运行,从逻辑上将整个集合传递到聚合管道。
为了尽可能优化操作,请使用一下策略以避免扫描整个集合(类似于MySQL中的全表扫描)。
管道阶段使用索引
- match出现在管道的开始,该阶段可以使用索引来过滤文档。
- project、group阶段,$sort就能使用索引。
-
group阶段可以使用索引查找每个组中的第一个文档:
- sort阶段,该阶段对字段进行分组。
- 在分组的字段上有一个索引,它与排序顺序匹配
- first
- geoNear必须出现在管道的第一阶段。
早期过滤
如果聚合操作仅需要集合中的数据子集,请使用limit, match操作使用合适的索引,来扫描集合中匹配的文档。
内部优化阶段
聚合管道中有内部优化阶段,这是一个大话题,后期再说。
聚合管道优化
管道操作符
管道操作符是用于描述管道各个阶段所做操作的类型。比如group,表示对文档分组。
结束
本篇仅了解管道相关的一些概念,未来会写一篇关于实际操作的博客
网友评论