MongoDB Aggregation

对数据进行聚合操作,然后将计算之后的数据返回。聚合操作将多个文档的值组合在依赖,并且可以对分组数据执行各种操作返回单个结果。
MongoDB提供三种方式来执行聚合操作:aggregation pipeline、map-reduce function、single purpose aggregation methods。

1.Aggregation Pipeline

MongoDB 聚合操作是在数据处理管道的逻辑上建模的。documents可以进入一个用于处理docuemnt然后返回聚合值的多阶段管道。

底层的管道提供了filters(类似于查询的操作)和document transformations(修改document的输出形式)操作。

其他管道操作为document指定具体的属性或者多个属性进行分组和排序,以及用array内容的聚合工具一样。管道的阶段可以使用运算符执行任务。

管道使用MongoDB自带的本地操作来执行聚合操作更高效,管道是MongoDB执行聚合操作的首先。

聚合管道可以操作分片collection。聚合管道可以通过使用索引来提高性能。聚合管道内部会进行优化阶段。

1.1 Aggregation Pipeline Optimization

可以使用db.collection.aggregate()的explain参数看到执行计划。

1.1.1 Projection Optimization

聚合管道来决定需要返回的字段。如果使用只需要的字段,这样可以减少数据量。

1.1.2 Pipeline Sequence Optimization

addFields + match放入到addFields之前(如果是project / $addFields的结果,就不能移动),减少数据量。

match: 先执行$match来减少数据量,然后在执行排序操作。

match: 如果在前面添加$match操作,可以使用索引来减少数据操作。

skip(在3.2开始可以使用):将project操作之前,可以减少数据量。

1.1.3 Pipeline Coalescence Optimization

通常情况下,在重新排序优化之后才会发生阶段合并。

limit:如果不能减少数据量,不会将这两个阶段合并。否则先进行排序,然后获取指定的数量,放入内存。如果在中间含有$skip操作,将其放入最后。
在数据量超过内存限制,这个操作需要设置 allowDiskUse=true。

1.2.Aggregation Pipeline Limits

1.2.1 Result Size Restrictions

从MongoDB3.6开始,删除了aggregate的选项,将结果作为一条数据的返回。

aggregate可以返回cursor或者数据结果集。在返回的结果中,每个document的大小不能超过16M(这个限制只针对返回的document)。
documents有可能会超过这个限制,db.collection.aggregate()默认返回cursor。

1.2.2 Memory Restrictions

从MongoDB2.6开始,管道阶段的RAM限制为100M。如果超过限制,出错。如果为了处理大量的数据集,使用allowDiskUse选项开启管道阶段的聚合操作将数据写入到临时文件。

从MongoDB3.4之后,graphLookup操作会忽略这个选项。如果其他阶段有aggregate()操作,allowDiskUse=true将会影响这些阶段。

1.3.Aggregation Pipeline and Sharded Collections

1.3.1 Behavior

从MongoDB3.2开始,如果按照分片来匹配值,只会在这个分片内进行计算。

聚合操作在多个分片上执行操作,如果没有指定主分片,这些操作会被路由到其他分片上,来减少主分片的负载。

lookup阶段需要在主分片上执行查询。

1.3.2 Optimization

将聚合管道拆分为两部分,这是为了在分片上执行优化。

操作可以参考实例

2. MapReduce

2.1 Map-Reduce and Sharded Collections

MapReduce可以在分片上执行操作,分片集合可以作为输入或者输出。

2.1.1 Sharded Collection as Input

使用分片集合作为MapReduce输入源,mongos将作业并行派发到各个分片。mongos会等待所有的作业完成。

2.1.2 Sharded Collection as Output

如果MapReduce的out字段有分片值,MongoDB使用_id字段作为分片的依据。

作为一个分片集合输出:

  • 如果输出集合不存在,MongoDB按照_id属性来创建和分片集合。
  • 从4.0开始之后,如果输出集合存在但是没有分片,mapreduce就会失败。
  • 对于新的分片集合或者空的分片集合,MongoDB使用第一个阶段的结果来创建分片中初始分片块。
  • mongo并行分发作业到每一个分片上。
  • 在MapReduce执行任务时,MongoDB会删除数据块。在后处理期间会自动阻止对输出集合的块进行平衡,以避免并发问题。

2.2 Map-Reduce Concurrency

在操作的过程中,mapreduce有很多锁:

  • 读阶段采用读锁定。每100个document产生一个读锁。
  • 在写阶段,每一个document拥有一个写锁。
  • 如果输出集合不存在,创建输出集合会获取一个写锁。
  • 如果输出集合存在,输出动作会获取一个写锁。这个锁是全局的,锁定mongodb实例所有的操作。

相关练习教程

你可能感兴趣的:(MongoDB Aggregation)