count
最简单的聚合工具,返回集合中的文档数量,速度非常快。
>db.coll.count()
计算查询条件为name是xiaozhe的总数,有条件的查询速度会变慢。
>db.coll.count({"name":"xiaozhe"})
distinct
用来找出给定键的所有不同值,使用时必须指定集合和键。
>db.runCommand({"distinct":"coll","key":"age"})
group
先选定分组所依据的键,而后MongoDB就会将集合依据选定键值的不同分成若干组。然后可以通过聚合每一组内的文档,产生一个结果文档。类似sql中的Group
例子:现在我们需要从下面文档得到最近30每天最后时刻(time)的价格
我们先将集合按照天分组,然后在每一组里取包含最新时间戳的文档,将其放置到结果中就完成了。
>db.runCommand({"group":{
"ns":"stocks",
"key":"day",255); font-size:10.5000pt; font-family:'宋体'">"initial":{"time":0},255); font-size:10.5000pt; font-family:'宋体'">"$reduce":function(doc,prev){
if(
prev.price
prve.time
}
},255); font-size:10.5000pt; font-family:'宋体'">"condition":{"day":{"$gt":"2010/09/30"}}
}})
现在我们分解上面的命令:
"ns":"stocks"
"key":"day" #指定文档分组的键,所有day值相同的划分到一组
"initial":{"time":0} #每一组reduce函数调用的初始时间,会作为初始文档传递给后续过程。每一组的所有成员都会使用这个累加器,所以改变会保留住。
#每个文档都对应这一次调用,系统会传递2个参数:当前文档和累加器文档(本组当前的结果)。本例中,想让reduce函数比较当前文档的时间和累加器的时间。
"condition":{"day":{"$gt":"2010/09/30"}} #分组的条件,有些资料提及cond或q,其实和condition键是一样的意思。
finalize
完成器可以精简从数据库传到用户的数据,这个步骤非常重要,因为group命令的输出一定要放在单个数据库响应中。
具体实例:PAGE
将函数做为键使用
有时候分组的依据条件非常复杂,不仅仅是一个键。比如要计算有多少篇不同类别的文章,但是由于作者建立类别的时候大小写不注意。造成两种不同的结果,为了消除这种影响,我们需要定义一个函数来确定文档分组依据的键。
注意:定义分组函数就要用到$keyf键(注意不是$key)。
>db.coll.group({
"ns":"coll",
"$keyf":function
Return
},
...
})
MapReduce
PAGE
MapReduce是聚合工具中的明星。Count,distinct,group能做的上述事情MapReduce都能做。它是一个可以轻松并行化到多个服务器的聚合,它会拆分问题,再将各个部分发送到不同的的机器上,让每个机器完成一部分,当所有机器都完成的时候,再把结果汇总形成最终结果。