一. 简介
如果你有数据存储在mongo里面,需要对数据进行分析和利用。可以利用如下几个工具:
1. 聚合框架
2. MapReduce
3. 聚合命令:count,distinct和group
二. 聚合框架
2.1 介绍
有一个保存杂志文章的集合,你希望找出发表文章最多的5个作者,每一篇文章是一个文档。可以如下执行查询:
db.articles.aggregate( {"$project":{"author":1}, //将作者从文档里面映射出来,文档结果是{"_id":id, "author":authorname}
{"$group" : {"_id":"$author", "count":{"$sum":1} } }, // 将文档按照作者统计次数,一个作者变成一个文档。 结果是{"_id":authorname, "count": articleCount}
{"$sort" : {"count": -1} }, //按照次数降序排列
{"$limit" : 5} ) // 取前面5个
这个类似linux里面的管道,前一步的执行结果作为下一步的输入。(需要注意返回结果要小于16M,这是mongoDB支持的最大响应体)
2.2 管道操作符
前面的$project,$group 等都是管道操作符
2.2.1 $match
用于文档集合进行筛选,相当于where条件,比如想找到作者为wenchao的发布的文章{$match : {"author":"wenchao"}}。match尽量放在第一个位置,快速过滤文档
2.2.2 $project
用于从文档提取字段,相当于select.
2.2.3 $group
分组,相当于group,例子
db.scores.aggregate {
{
"$group" : {
"_id" : "$grade", //年级分组
"lowScore" : {"$min" : "$score"}, //每个年级最低分
"highScore": {"$max" : "$score"} //每个年级最高分
}
})
2.2.4 $unwind
拆分,将数组拆分成1个个独立文档
2.2.5 $sort
排序,建议尽早进行,利用索引。
2.2.6 $limit
限制返回结果条数
2.2.7 $skip
接收一个数字n,表示丢弃结果集中前n个文档
2.2 MapReduce
MapReduce是聚合界的明星,非常灵活和强大,但又过于复杂。如果无法用聚合框架实现的功能,可以用MapReduce。由于慢,不适合实时查询,适用离线计算。可以参考如下文章了解:
2.3 聚合命令
2.3.1 count
返回文档集合中的文档数量。比如,db.foo.count()
2.3.2 distinct
找出给定键的不同值
db.runCommand({"distinct": "people", "key": "age"})
找出people集合中age列的所有不同值
2.3.3 group
分组,假设每一篇博客都有多个标签,现在要找出每一天最热门的标签。
如果分组键需要进行一些处理,可以定义函数,如下所示:
db.post.group ({
"ns":"post",
"$keyf": function(x){return x.catgory.toLowCase();}, //按照分类小写分组
"initalizer":.................
..................
})