在mongodb中想要完成聚合操作,可以使用以下三种方式;但是很多时候这三个真是傻傻分不清楚,本文是来总结以下三种方式的区别滴~
1. 聚合框架aggregate pipeline
2. mapreduce
3. 聚合命令group,distinct,count
聚合框架 aggregate pipeline(聚合管道)
aggregate 聚合框架是基于数据处理管道模型建立的,文档通过多级管道将会输出聚合结果;aggregate管道聚合方案使用的是mongodb内置的汇总操作,相对来说更为高效,在做mongodb数据聚合操作的时候优先推荐aggregate;
aggregate能够通过索引来提升性能,并且有一系列的管道性能优化操作这个优化总结另有文章描述;
总的来说aggregate管道操作有点像unix 系统内的管道操作,将当前文档进入第一个管道节点处理完成后再丢给第二个管道节点,举例子如下:
aggregate的限制
1.当aggregate返回的结果集(指针或者结果集),当结果集中的单个文档超过16 MB命令会报错;该限制只适用于返回的结果集文档,在管道处理文档的过程中,这个文档很有可能会超过16MB;
2.如果使用aggregate不指定游标选项或存储集合中的结果,aggregate命令返回一个包涵于结果集的字段中的bson文件。如果结果集的总大小超过bson文件大小限制(16MB)该命令将产生错误;
3.管道处理阶段有内存限制最大不能超过100MB,超过这个限制会报错误;为了能够处理更大的数据集可以开启allowDiskUse选项,可以将管道操作写入临时文件;
使用场景:
1.用于常用聚合操作
2.对聚合响应性能需要一定要求时(索引及组合优化)
3.aggregate 管道操作是在内存中完成的,有内存大小限制,处理数据集大小有限;
Mapreduce
Map-reduce是处理聚合计算的另外一个方式;Map-reduce一般有两个阶段:一个阶段是处理单个文档,另一个阶段是将处理完的当前文档返回一个或者多个对象进入下一个文档处理方法中;
额....好绕,简单来说就是reduce文档结果集,通过reduce函数进行汇总;
reduce不用我来解释吧!
Map-reduce使用惯用的javascript操作来做map和reduce操作,因此Map-reduce的灵活性和复杂性都会比aggregate pipeline更高一些,并且相对aggregate pipeline而言更消耗性能;
使用场景:
1.因为使用javascript灵活度高的特点,可以处理复杂聚合需求;
2.使用于处理大数据结果集
详细使用说明看这里MongoDB Mapreduce详细操作总结
单独的聚合命令(group,distinct,count)
一句话,比aggregate性能低,比Map-reduce灵活度低;但是可以节省几行javascript代码,后面那句话我自己加的,哈哈哈~
Group操作:mongodb2.2版本对于返回数据最多只包涵20000个元素,最多支持20000独立分组;对于超过20000的独立分组建议采用mapreduce;
Count操作:db.collection.count()等效于db.collection.find().count(),在分布式集合中,会出现计算错误的情况,这个时候推荐使用aggregate;
Distinct操作:可以使用索引;