6.mongodb聚集分析
6.1管道模式进行聚集分析
管道模式类似于流水线作业,第一道工序对数据处理之后,将处理后的数据交给第二道工序,依此类推。
如下图所示:
常用的管道操作符 | |
$match | 过滤文档,只传递匹配的文档到管道中的下一个步骤。 |
$limit | 限制管道中文档的数量。 |
$skip | 跳过指定数据段的文档,返回剩下的文档。 |
$sort | 对所有的文档进行排序。 |
$group | 对所有文档进行分组然后聚集计算。 |
$out | 将管道中的文档输出到一个具体的集合中,这个必须是管道操作的最后一步。 |
与$group操作一起使用的计算聚集值得操作符有如下: | |
$first | 返回group后的第一个值。 |
$last | 返回group后的最后一个值。 |
$max | 返回group后的最大值。 |
$min | 返回group操作后的最小值。 |
$avg | 返回group操作后的平均值。 |
$sum | 返回group操作后所有值得和。 |
常用SQL语句与Mongodb语句对比 | |
Select count(*) as count from books | >db.customers.aggregate([{$group:{_id:null,count:{$sum:1}}}]) { "_id" : null, "count" : 57 } |
Select sum(num) as total from books | >db.customers.aggregate([{$group:{_id:null,total:{$sum:"$id"}}}]) { "_id" : null, "total" : 10 } |
Select book_id,sum(num) as total from books group by book_id | >db.customers.aggregate([{$group:{_id:"$name",total:{$sum:"$id"}}}]) { "_id" : "xiaoming", "total" : 10 } { "_id" : "brown2", "total" : 0 } |
Select book_id,status,sum(num) as total from books group by book_id,status | >db.costomers.aggregate([{$group:{_id:{id:"$id",name:"$name"},total:{$sum:"$id"}}}]) |
Select book_id, count(*) from books group by book_id having count(*)>1 | db.costomers.aggregate([{$group:{_id:{id:"$id",name:"$name"},total:{$sum:"$id"}}},{$match:{count:{$gt:1}}}]) |
6.2mapreduce模式聚集
Mongodb提供了当前流行的mapreduce的并行编程模型,为海量数据的查询分析提供了一种更加高效的方法,用mongodb做分布式存储,然后利用mapreduce来做分析。
实例:
如图所示:
代码如下:
Db.books.mapreduce({
Function(){emit(this.book_id,this.num);},
Function(key,values){return Array.sum(values);},
{
Query:{status:"normal"},
Outresult:"books_totals"
}
})
代码分析:
以上相当于关系数据库中如下sql
Select sum(num) as value,book_id as _id 6yh from books where status ="normal" group by book_id
Mapreduce的解决方案:
- 定义一个map
Function(){emit(this.book_id,this.num);}
- 定义reduce
Function(key,values){return Array.sum(values);}
- 执行mapreduce函数
Query:{status:"normal"},返回状态为normal的值,同时定义了保存结果的集合名,最后的输出结果将保存在集合books_totals中。
注意:这里的map、reduce函数都是利用javascript编写的函数,其中map函数的关键部分是emit(key,value)函数,此函数的调用使集合使集合中的document对象按照key值生成一个value,形成一个键值对。其中key可以单一field,也可以由多个field组成,mongodb会按照key生成对应的value值,value为一个数组。
Reduc函数的定义中有参数key和value,其中key就是上面map函数中指定的key值,value就是对应key对应的值,Array.sum(value)这里是对数组中的值求和,按照不同的业务需要,我们可以编写自己的js函数来处理。
6.3简单聚集函数
管道模式和mapreduce模式基本上可以解决数据分析中的所有问题,但有时候在数据量不是很大的情况,使用基于集合的函数会更简单。
如下是常用的聚集集合函数:
- distinct函数,用于返回不重复的记录。
Db.orders.distinct(key,<query>)
Key:field
Query:查询选择器
- count函数,用于查询总记录数目。
Db.collection.find(<query>)
- group函数
此函数和dicinct函数一样不能大于16mb,不能再分片集群上进行操作,不能处理超过10000个唯一主键。
Db.collection.group({key:{},initial:{},reduce:{},cond:{}})
实例:
Db.books.group(
Key:{_id:1},
Cond:{_id:{$lt:3}},
Reduce:function(cur,result)
{
Result.count+=cur.count
},
Initial:{count:0}
)

浙公网安备 33010602011771号