总述
MongoDBAggregation(聚合)框架用来实现类似关系型数据库中的group等运算和同一记录中不同字段之间的运算(这个在MongoDB 中通过find()命令是不能实现的)。
MongoDB的聚合的实现是以一种流水线(或称作“管道“)的方式,“数据元素”流串行地被一组线程按顺序执行,如下图:
在这个流水线上主要有如下几个工序:过滤(filtering)、映射(projecting)、分组(grouping)、排序(sorting)、限制(limiting)和跳过(skiping)。这些工序中最基本的是过滤和映射,过滤用来滤去不需要的字段,而映射则进行相关变换并最终以用户需要的形式输出。各个工序在流水线上环环相扣的,一个工序接到数据并处理后,结果将作为下个工序的输入传送到下个工序上。
下面举个例子来具体说明一下,比如你有一些文章,你想知道这些文章中哪个作者写的比较多。假设它们存储在MongoDB中,每个文档表示一篇文章,包含文章标题和作者等属性。想一想,如果在关系型数据库中,我们该怎么实现呢?肯定是按作者分组,然后求得同一作者的文章数的和,最后把文章数较多的几个作者列出来。这个过程中我们需要展示作者列,还要生成一个文章总数列并展示出来。大致SQL如下:
SELECTauthor,count(article_title) --过滤取得需要的列,同时计算每个作者的文章数
FROMarticles
GROUPBY author --分组
ORDERBY count(article_title) DESC; --排序
在MongoDB中,原理上也就需要这么几步:
1、提取需要的列——作者列;
2、按作者列分组,并计算各作者的文章数;
3、按照文章数倒序排序,得到文章较多的几个作者;
4、限制显示文章产量头几名的作者;
具体到在MongoDB中的写法如下:
> db. articles. aggregate(
... {"$project" : {"author" : 1}},
... {"$group": {"_id" : "$author" , "count" : {"$sum" : 1}}},
... {"$sort": {"count" : - 1}},
... {"$limit" : 5})
简单说明下这几个操作符(关于各聚合操作符的用法在后面详述):
1、aggregate()表示这是一个聚合查询,各聚合操作都在它的里边工作;
2、$project实现诸如抽取必需字段,字段重命名等功能;
3、$group实现分组,此例中以author分组,分组后,每个作者将是一个文档,故文档的_id采用author,注意这里使用$author表示引用原来的author字段作为_id的值。同时产生一个新列count,值就是计算得到的文档的数目。$sum表示在分组的时候,每碰到一个同组的document就加1。
4、$sort,顾名思义就是排序,与在find()后出现时的用法类同;
5、$limit,表示只返回文章数量最多的前5个作者。
注意:MongoDB的聚合运算是在内存中进行的,结果直接返给客户端,不能回写到库中。这就要求产生的结果不能太大,不超过16M。