MongoDB之MapReduce统计详解大数据
MongoDB之MapReduce相当于关系型数据库中的group by,主要用于统计数据之用。
在MongoDB javascript Shell中对Array对象进行了一些扩展,其中新增sum方法,以方便统计数据之用的。
Array.sum
function(arr){
if(arr.length == 0)
return null;
var s = arr[0];
for(var i = 1; i arr.length; i++)
s += arr[i];
return s;
}
而在浏览器端,js原生没有为Array提供sum方法的。
Array.sum为undefined。
先插入一些测试用的数据
db.mythings.insert({location: Guangzhou , age:20, name: j })
db.mythings.insert({location: Guangzhou , age:21, name: ji })
db.mythings.insert({location: Beijing , age:22, name: jim })
db.mythings.insert({location: Beijing , age:23, name: jimv })
db.mythings.insert({location: Guangzhou , age:25, name: jimvi })
db.mythings.insert({location: Shanghai , age:25, name: jimvin })
需求1:统计不同地方(‘Guangzhou,Beijing,Shanghai’)的人的岁数总和
var map = function(){ emit(this.location, this.age); }
var reduce = function( key, values ){ return Array.sum(values); }
var options = { out: age_totals }
db.mythings.mapReduce( map, reduce, options )
显示结果:
db.age_totals.find()
{
_id : Shanghai ,
value : 25
}
{
_id : Guangzhou ,
value : 66
}
{
_id : Beijing ,
value : 45
}
需求2:统计不同地方(‘Guangzhou,Beijing,Shanghai’)的人数总和
var map = function(){ emit(this.location, 1); }
var reduce = function( key, values ){ return Array.sum(values); }
var options = { out: person_totals }
db.mythings.mapReduce( map, reduce, options )
显示结果:
db.person_totals.find()
{
_id : Shanghai ,
value : 1
}
{
_id : Guangzhou ,
value : 3
}
{
_id : Beijing ,
value : 2
}
需求3:统计不同地方(‘Guangzhou,Beijing,Shanghai’)的人名列表
var map = function(){ emit(this.location, this.name); }
var reduce = function( key, values ){ return values.join( , ); }
var options = { out: name_totals }
db.mythings.mapReduce( map, reduce, options )
显示结果:
db.name_totals.find()
{
_id : Shanghai ,
value : jimviv
}
{
_id : Guangzhou ,
value : j, ji, jimvi
}
{
_id : Beijing ,
value : jim, jimv
}
需求4:统计不同地方(‘Guangzhou,Beijing,Shanghai’),并且年龄在25岁(不包括25岁)以下的人名列表
var map = function(){ emit(this.location, this.name); }
var reduce = function( key, values ){ return key + : + values.join( , ); }
var options = { query: { age: {$lt: 25} }, out: name_totals }
db.mythings.mapReduce( map, reduce, options )
显示结果:
db.name_totals.find()
{
_id : Guangzhou ,
value : Guangzhou: j, ji
}
{
_id : Beijing ,
value : Beijing: jim, jimv
}
分析一下:
1. map部分
作用:用于分组的。
emit(param1, param2)
param1:需要分组的字段,this.字段名。
param2:需要进行统计的字段,this.字段名。
2. reduce部分
作用:处理需要统计的字段
var reduce = function(key, values){
统计字段处理
}
key: 指分组字段(emit的param1)对应的值
values:指需要统计的字段(emit的param2)值组成的数组
简单介绍统计常用的方法:
* 对数值类型进行求和
var reduce = function(key, values){
return Array.sum(values);
}
* 对字符串类型进行拼凑
var reduce = function(key, values){
return values.join( , );
}
3. options部分
{ query: { age: {$lt: 25} }, out: name_totals }
query:先筛选符合条件的记录出来,再进行分组统计。
out:将分组统计后的结果输出到哪个集合当中。
默认情况下,out所指定的集合在数据库断开连接后再次打开时,依旧存在,并保留之前的所有记录的。
4. 执行分组统计
db.集合名.mapReduce( map, reduce, options )
第二种写法(测试数据同上):
db.mythings.ensureIndex({location:1, name:-1})
var map = function(){ emit(this.location, this.name); }
var reduce = function( key, values ){ return key + : + values.join( , ); }
db.runCommand(
{
mapreduce: mythings
,map: map
,reduce: reduce
,out: a
,keeptemp: false
,query: { age:{ $lt: 25 }}
,sort:{ location:1, name:-1 }
}
)
显示结果:
db.a.find()
{
_id : Guangzhou ,
value : Guangzhou: ji, j
}
{
_id : Beijing ,
value : Beijing: jimv, jim
}
value的名字列表“ji,j” 和 “jim,jim” 都进行了降序排列,证明使用了sort功能。
解析:
mapreduce:
分组统计的集合名
举例:
mapreduce: mythings
不能写成mapreduce: mythings,否则报异常:mythings is not defined
注意:以下写法错误
var collection = db.mythings.find( { age: {$lt: 25} } )
db.runCommand(
{
mapreduce: collection
,map: map
,reduce: reduce
,out: a
,keeptemp: false
}
)
报错:{ ok : 0, errmsg : ns doesn t exist }
map,reduce :
同上,不做阐述
out :
将分组统计结果输出到某个集合。
注意:不能缺省,必须指定名称,否则报错,报错如下:
“exception: out has to be a string or an object”
keeptemp :
是否保留临时集合(指out指定的集合)
keeptemp:false时会在数据库断开连接后,MongoDB会移除该集合的所有记录。而不是删除。
keeptemp:true时即使数据库断开连接后,再次连接上,该临时集合依旧保持之前所有记录。
keeptemp默认值为true。
query :
筛选记录后,再进行分组统计
举例:
query: { age:{ $lt: 25 }}
sort :
对分组统计的集合进行排序,也即先排序,后再执行分组统计的。
注意:这里的排序需要用到索引,必须先创建索引。
举例:
db.mythings.ensureIndex({location:1, name:-1})
var map = function(){ emit(this.location, this.name); }
var reduce = function( key, values ){ return key + : + values.join( , ); }
db.runCommand(
{
mapreduce: mythings
,map: map
,reduce: reduce
,out: a
,sort:{ location:1, name:-1 }
}
)
limit :对分组统计的集合先进行限制返回记录的条数,然后再去进行统计操作。注意:不要理解成对统计后的结果进行限制返回记录条数。
db.mythings.ensureIndex({location:1, name:-1})
var map = function(){ emit(this.location, this.name); }
var reduce = function( key, values ){ return key + : + values.join( , ); }
db.runCommand(
{
mapreduce: mythings
,map: map
,reduce: reduce
,out: a
,keeptemp: false
,query: { age:{ $lt: 25 }}
,sort:{ location:1, name:-1 }
,limit:3
}
)
结果:
{
_id : Guangzhou ,
value : ji
}
{
_id : Beijing ,
value : Beijing: jimv, jim
}
verbose :
显示时间统计信息,取值为true/false
举例:
var map = function(){ emit(this.location, this.name); }
var reduce = function( key, values ){ return key + : + values.join( , ); }
db.runCommand(
{
mapreduce: mythings
,map: map
,reduce: reduce
,out: a
,verbose: true
}
)
在cmd控制台返回了以下结果
{
result : a
“timeMillis”:3
“timeing”:{
“mapTime”: 0
,“emitLoop”: 2
,“reduceTime”: 0
,“mode”: mixed
,“total”: 3
}
}
其中“timeing”就是对应的详细耗时信息。
finalize:
function(key, reducedValue){
return obj;
}
key: 指分组字段(emit的param1)对应的值
reducedValue:指reduce返回的结果
举例:
var final = function(key, reducedValue){
var obj = {};
obj.key = key;
obj.reducedValue = reducedValue
return obj;
}
var map = function(){ emit(this.location, this.name); }
var reduce = function( key, values ){ return key + : + values.join( , ); }
db.runCommand(
{
mapreduce: mythings
,map: map
,reduce: reduce
,out: a
,finalize: final
}
)
结果:
{
_id : Guangzhou ,
value : {
key : Guangzhou ,
reducedValue : Guangzhou: ji, j
}
}
{
_id : Beijing ,
value : {
key : Beijing ,
reducedValue : Beijing: jimv, jim
}
}
scope:
为finalize、map、reduce指定this指针的作用域。
注意:不是像MongoDB权威指南中文版.pdf 所说的为finalize、map、reduce导入外部变量。
举例:
var final = function(key, reducedValue){
var obj = {};
obj.scope = this.scope;
obj.key = key;
obj.reducedValue = reducedValue
return obj;
}
var map = function(){ emit(this.location, this.name); }
var reduce = function( key, values ){ return key + : + values.join( , ); }
db.runCommand(
{
mapreduce: mythings
,map: map
,reduce: reduce
,out: a
,finalize: final
,scope:{scope:4}
}
)
结果:
{
_id : Guangzhou ,
value : {
scope : 4,
key : Guangzhou ,
reducedValue : Guangzhou: ji, j
}
}
{
_id : Beijing ,
value : {
scope : 4,
key : Beijing ,
reducedValue : Beijing: jimv, jim
}
}
转载请注明来源网站:blog.ytso.com谢谢!
原创文章,作者:Maggie-Hunter,如若转载,请注明出处:https://blog.ytso.com/9701.html
分布式文件系统,分布式数据库区块链并行处理(MPP)数据库,数据挖掘开源大数据平台数据中台数据分析数据开发数据治理数据湖数据采集相关文章
- Mongodb基本操作与Python连接mongodb并进行基础操作的方法
- mongodb sharding 的安装( replica set + sharding)详解大数据
- MongoDB之旅:实用的客户端工具(mongodb客户端工具)
- MongoDB利用索引加速数据存取(mongodb存储索引)
- 分析MongoDB磁盘空间使用情况分析(mongodb磁盘空间)
- MongoDB数据存储之路:实现极致的性能(mongodb数据路径)
- MongoDB数据导出查询实践(mongodb导出查询)
- MongoDB:实现数据库自定义设置(mongodb设置)
- MongoDB实现高效的搜索功能(mongodb搜索)
- MongoDB稳步升级,提升数据库性能(mongodb升级)
- 表MongoDB查询:获取列表中的数据(mongodb查询列)
- Mongodb轻松创建新数据库,提高数据存储效率(mongodb新建数据库)
- MongoDB存储:高效、稳定、灵活的数据管理方案(mongodb存储)
- 解决MongoDB数据丢失和恢复(mongodb丢数据)
- 从MongoDB表中快速复制数据(mongodb表复制)
- 如何高效的使用 MongoDB 进行数据清理?(mongodb清理数据)
- MongoDB免费,数据存储又省钱了!(mongodb免费)
- Mongodb日志存储:保护数据的必备步骤(mongodb日志存储)
- 立Mongodb:开启创新之路,树立持续发展新梦想(mongodb树)
- MongoDB:高效的文档修改方式(mongodb文档修改)
- MongoDB 可视化分析:开启全新数据视界(mongodb可视化软件)
- MongoDB:安全保护实现数据加密(mongodb 加密)
- ETL从MongoDB中抽取数据的简单方法(etl抽取mongodb)
- MongoDB的事务回滚技术简介(mongodb事务回滚)