9.聚合函数count+distinct+group + MapReduce
2016-12-06 18:09
513 查看
1.max最大值 min最小值
mongoDB不像SQL那样有min() 和max()函数。但是可以通过sort排序和limit限制返回来得到想要的结果找到投票数helpful_votes**最多**的评论:(最大值,按照降序排列,并限制返回第1条记录)
db.reviews.find({}).sort({helpful_votes : -1}).limit(1)
找到投票数helpful_votes**最少**的评论:(最小值,按照升序排列,并限制返回第1条记录)
db.reviews.find({}).sort({helpful_votes : 1}).limit(1)
2.count()函数
请统计persons中美国学生的人数> db.persons.find({country:"USA"}).count() 3
3.distinct()函数
查询persons中一共有多少个国家,分别是什么?> db.persons.distinct("country") [ "USA", "China", "Korea" ]
或者:
> db.runCommand({distinct:"persons",key:"country"}).values [ "USA", "China", "Korea" ]
4.group()函数
语法:db.runCommand({group:{ ns:集合名称, key:分组的键对象, initial:初始化累加器, $reduce:组分解器, condition:条件, finalize:组完成器 }})
格式标准参照:
{ group: { ns:<namespace> , key:<key> , $reduce:<reduce function> , $keyf: <key function>, cond: <query>, finalize:<finalize function> } }
key:指定要分组的字段,可以使用复合键
keyf:为该文档生成一个临时键的JavaScript函数
initial:聚合结果初始值的
reduce:执行聚合函数的JavaScript函数
cond:过滤要聚合文档的查询选择器
finalize:在返回结果集前用于每个结果文档的JavaScript函数
分组首先会按照key进行分组,每组的每一个文档全要执行$reduce的方法,它接收2个参数,一个是组内本条记录,一个是累加器数据
4.1 请查出persons中每个国家学生数学成绩最好的学生信息(必须在90分以上)
db.runCommand({group:{ ns:"persons", //操作集合:persons key:{"country":true}, //操作的键:country initial:{m:0}, //初始化值:数学m:0 $reduce:function(doc,prev){ //组分解器:比较并保存m值较大的 if(doc.m > prev.m){ prev.m = doc.m; prev.name = doc.name; prev.country = doc.country; } }, condition:{m:{$gt:90} //过滤条件:m值比90分大的留下 } }})
运行结果:
{ "retval" : [ { "country" : "USA", "m" : 96, "name" : "jim" }, { "country" : "China", "m" : 96, "name" : "lisi" } ], "count" : 3, "keys" : 2, "ok" : 1 }
4.2 在4.1的基础上将个人信息组合起来,通过m进行输出
db.runCommand({group:{ ns:"persons", key:{"country":true}, initial:{m:0}, $reduce:function(doc,prev){ if(doc.m > prev.m){ prev.m = doc.m; prev.name = doc.name; prev.country = doc.country; } }, condition:{m:{$gt:90} }, finalize:function(prev){ prev.m = prev.name+" Math scores "+prev.m }}})
运行结果:
{ "retval" : [ { "country" : "USA", "m" : "jim Math scores 96", "name" : "jim" }, { "country" : "China", "m" : "lisi Math scores 96", "name" : "lisi" } ], "count" : 3, "keys" : 2, "ok" : 1 }
4.3用函数格式化分组的键
如果集合中出现键counrty和counTry同时存在,那分组有点麻烦,这要如何解决呢?
$keyf:function(doc){ return {country:doc.counTry} },…..
我们做一个小测试:
插入一行数据:
db.persons.insert({ name:"USPCAT", age:27, email:"2145567457@qq.com", c:89,m:100,e:67, counTry:"China", books:["JS","JAVA","EXTJS","MONGODB"] })
注意这个文档的“国家”键中“t”是大写的!
我们再次查询:
db.runCommand({group:{ ns:"persons", key:{"country":true}, initial:{m:0}, $reduce:function(doc,prev){ if(doc.m > prev.m){ prev.m = doc.m; prev.name = doc.name; prev.country = doc.country; } }, finalize:function(prev){ prev.m = prev.name+" Math scores "+prev.m }, condition:{m:{$gt:90}} }})
查询结果是这样的:
{ "retval" : [ { "country" : "USA", "m" : "jim Math scores 96", "name" : "jim" }, { "country" : "China", "m" : "lisi Math scores 96", "name" : "lisi" }, { "country" : null, "m" : "USPCAT Math scores 100", "name" : "USPCAT" } ], "count" : 4, "keys" : 3, "ok" : 1 }
发现第三条数据的country值是null,这是因为数据结构的不规范造成的,解决问题如下:
我们将新增的counTry字段的值给country
增加$keyf选项:
$keyf:function(doc){ if(doc.counTry){ return {country:doc.counTry} }else{ return {country:doc.country} } }
再次查询:
{ "retval" : [ { "country" : "USA", "m" : "jim Math scores 96", "name" : "jim" }, { "country" : "China", "m" : "USPCAT Math scores 100", "name" : "USPCAT" } ], "count" : 4, "keys" : 2, "ok" : 1 }
5. map-reduce
Map-Reduce是一种计算模型,简单的说就是将大批量的工作(数据)分解(MAP)执行,然后再将结果合并成最终结果(REDUCE)。MongoDB提供的Map-Reduce非常灵活,对于大规模数据分析也相当实用。
>db.collection.mapReduce( function() {emit(key,value);}, //map 函数 function(key,values) {return reduceFunction}, //reduce 函数 { out:collection, query: document, sort: document, limit: number } )
使用 MapReduce 要实现两个函数: Map 函数和 Reduce 函数
Map 函数调用 emit(key, value), 遍历 collection 中所有的记录, 将key 与 value 传递给 Reduce 函数进行处理。
Map 函数必须调用 emit(key, value) 返回键值对。
参数说明:
• map :映射函数 (生成键值对序列,作为 reduce 函数参数)。
• reduce 统计函数,reduce函数的任务就是将key-values变成key-value,也就是把values数组变成一个单一的值value。。
• out 统计结果存放到集合 (不指定则使用临时集合,在客户端断开后自动删除)。
• query 一个筛选条件,只有满足条件的文档才会调用map函数。(query。limit,sort可以随意组合)
• sort 和limit结合的sort排序参数(也是在发往map函数前给文档排序),可以优化分组机制
• limit 发往map函数的文档数量的上限(要是没有limit,单独使用sort的用处不大)
> db.posts.mapReduce( ... function() { emit(this.user_name,1); }, ... function(key, values) {return Array.sum(values)}, ... { ... query:{status:"active"}, ... out:"post_total" ... } ... ) { "result" : "post_total", "timeMillis" : 214, "counts" : { "input" : 5, "emit" : 5, "reduce" : 1, "output" : 2 }, "ok" : 1, }
> db.posts.mapReduce( ... function() { emit(this.user_name,1); }, ... function(key, values) {return Array.sum(values)}, ... { ... query:{status:"active"}, ... out:"post_total" ... } ... ).find() 运行结果: { "_id" : "mark", "value" : 4 } { "_id" : "runoob", "value" : 1 }
相关文章推荐
- Mongodb中数据聚合之基本聚合函数count、distinct、group
- MongoDB聚合(count、distinct、group、MapReduce)
- 当HQL中的count遇上distinct/groupby
- MongoDB学习笔记——聚合操作之group,distinct,count
- MongoDB count distinct group by JavaAPI查询
- group后count中既包含字段(可DISTINCT去重)又包含条件过滤
- HIVE group by 和count(distinct)进行对比
- mongo中的高级查询之聚合操作(distinct,count,group)
- spark【例子】count(distinct 字段) 简易版 使用groupByKey和zip
- MongoDB教程之聚合(count、distinct和group)
- mysql中用distinct查询多条不重复记录值 group count
- MongoDB教程之聚合(count、distinct和group)
- Mongodb聚合函数count、distinct、group如何实现数据聚合操作
- MongoDB教程之聚合(count、distinct和group)
- MapReduce功能实现五---去重(Distinct)、计数(Count)
- MongoDB快速入门(十三)- 聚合count、distinct和group
- MDX Step by Step 读书笔记(七) - Performing Aggregation 聚合函数之 Max, Min, Count , DistinctCount 以及其它 TopCount, Generate
- 当HQL中的count遇上distinct/groupby
- Mongodb聚合函数count、distinct、group如何实现数据聚合操作
- spark【例子】count(distinct 字段) 简易版 使用groupByKey和zip