mongodb聚合命令分为三种:aggregate管道、mapreduce JavaScript函数、group JavaScript函数,以下是它们的对比
| aggregate | mapreduce | group |
描述 | 2.2新版功能 设计的初衷是为了提高执行效率和聚合任务的可用性。使用管道(例如$group,$match,$sort)访问相关对象 | 使用mapreduce聚合处理大数据集 | 提供分组功能。 性能比aggregate慢并且功能没有mapreduce强大 |
主要特征 | 管道操作能被重复使用,针对每一个输入文档不必都产生一个输出文档。能够生成新的文档或者对输出文档进行过滤操作。 | 除了分组操作之外,还能执行复杂的聚合任务以及在不断增长的数据集上做增量聚集。 | 能够对已经存在的字段进行分组,也能够利用自定义的 keyf JavaScript函数,还能够对计算之后的字段进行分组 |
灵活性 | 受限于聚合管道的操作函数和表达式。然而它也能添加计算过的字段、创建新的虚拟子对象、使用$project管道将子集字段提取到结果集的顶层 | 需要自定义map、reduce和finalize JavaScript函数提供灵活的聚合逻辑 | 需要自定义reduce和finalize JavaScript函数提供灵活的聚合逻辑 |
输出结果集 | 返回各种可选的结果集(包含有结果集的文档,结果集的游标)。 如果返回的是包含结果集的文档则会有大小限制,不得超过BSON文档的大小(16M)。 在2.6版本后:能返回一个结果集的游标或者存储结果集的集合 | 返回各种可选的结果集(内联,新集合,合并,替换,化简)。 在2.6版本后:更好的支持在分片上的map-reduce操作 | 返回内联的结果集,以分组项的数组形式。 结果集的大小必须小于BSON文档的大小(16M)。 在2.2版本之后:返回的结果集数组能包含20000个元素,即可以对20000个不同的元素进行分组操作,以前版本仅支持10000个 |
分片 | 支持不分片和分片的输入集合 | 支持不分片和分片的输入集合 | 不支持分片的输入集合 |
注意 |
| 2.4版本以前JavaScript函数是单线程执行 | 2.4版本以前JavaScript函数是单线程执行 |
使用aggregate管道有以下限制:
1. 结果集大小限制
如果aggregate命令返回的是包含所有结果集的文档,那么文档大小不得超过16M,否则命令会报错。当然也可以返回一个游标或者把结果集存到一个集合中,则可以规避这个问题。
2. 内存限制
一般的,我们使用管道操作都是多阶段的,每个阶段可以使用的内存最多100M。如果某个阶段操作这个限制,mongodb就会报错。如果需要处理大量数据,可以在使用
aggregate命令是将allowDiskUse属性设置成true,这样管道会把数据写入临时文件。在聚合管道操作中$sort操作在2.6版本以前占用的最大内存大小是RAM的10%,2.6版本后被改成了100M