9.聚合函数count+distinct+group+MapReduce 1.max最⼤值 min最⼩值
mongoDB不像SQL那样有min() 和max()函数。但是可以通过sort排序和limit限制返回来得到想要的结果
到投票数helpful_votes**最多**的评论:(最⼤值,按照降序排列,并限制返回第1条记录)
到投票数helpful_votes**最少**的评论:(最⼩值,按照升序排列,并限制返回第1条记录)
请统计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" ]
语法:
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; untry = untry; }
}, 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; untry = untry; }
}, 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,
distinct查询"keys" : 2,
"ok" : 1
}
4.3⽤函数格式化分组的键
如果集合中出现键counrty和counTry同时存在,那分组有点⿇烦,
这要如何解决呢?
$keyf:function(doc){
return {unTry}
},…..
我们做⼀个⼩测试:
插⼊⼀⾏数据:
db.persons.insert({
name:"USPCAT",
age:27,
email:"2145567457@qq",
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;
}
},
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){
unTry){
return {unTry}
}else{
return {untry}
}
}
再次查询:
{
"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⾮常灵活,对于⼤规模数据分析也相当实⽤。
&llection.mapReduce(
function() {emit(key,value);}, //map 函数
function(key,values) {return reduceFunction}, //reduce 函数
{
out:collection,
query: document,
sort: document,
limit: number
}
)
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论