zl程序教程

您现在的位置是:首页 >  数据库

当前栏目

MongoDB之MapReduce统计详解大数据

MongoDB统计数据 详解 MapReduce
2023-06-13 09:20:27 时间

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

}

}

MongoDB之MapReduce统计详解大数据

转载请注明来源网站:blog.ytso.com谢谢!

原创文章,作者:Maggie-Hunter,如若转载,请注明出处:https://blog.ytso.com/9701.html

分布式文件系统,分布式数据库区块链并行处理(MPP)数据库,数据挖掘开源大数据平台数据中台数据分析数据开发数据治理数据湖数据采集