MongoDB中MapReduce的使用方法详解

  • A+
所属分类:MongoDB

前言

玩过Hadoop的小伙伴对MapReduce应该不生疏,MapReduce的壮大且机动,它可以将一个年夜问题拆分为多个小问题,将各个小问题发送到分歧的机械上行止理,所有的机械都完成计算后,再将计算成果归并为一个完备的办理计划,这便是所谓的散布式计算。本文我们就来看看MongoDB中MapReduce的使用。

盘算用mongodb mapreduce之前必定要知道的事!!!

mapreduce实在是分批处置数据的,每一百次从新reduce处置,以是到reduce里的数据假如是101条,那就会分2次进入。

这导致的问题便是在reduce中 假如 初始化 var count = 0;在轮回中 count ++,末了输出的是1???

避免都办法是,把数据存在返回的value里,这个value是会在轮回进入reduce的时刻重用的。在轮回中 count += value.count就能把之前都100加上了!!!

还有假如只有一条数据,那它不会进入reduce,会直接返回。

下面是详细例子:

string map = @"大众
function() {
var view = this;
emit(view.activity, {pv: 1});
}"大众;
string reduce = @"大众 
function(key, values) {
var result = {pv: 0};
values.forEach(function(value){ 
result.pv += value.pv;
});
return result;
}"大众;
string finalize = @"大众
function(key, value){
return value;
}"大众;

mapReduce

MongoDB中的MapReduce可以用来实现更繁杂的聚合敕令,使用MapReduce主要实现两个函数:map函数和reduce函数,map函数用来天生键值对序列,map函数的成果作为reduce函数的参数,reduce函数中再做进一步的统计,好比我的数据集如下:

{"大众_id"大众 : ObjectId("大众59fa71d71fd59c3b2cd908d7"大众),"大众name"大众 : "大众鲁迅"大众,"大众book"大众 : "大众叫嚣"大众,"大众price"大众 : 38.0,"大众publisher"大众 : "大众人平易近文学出书社"大众}
{"大众_id"大众 : ObjectId("大众59fa71d71fd59c3b2cd908d8"大众),"大众name"大众 : "大众曹雪芹"大众,"大众book"大众 : "大众红楼梦"大众,"大众price"大众 : 22.0,"大众publisher"大众 : "大众人平易近文学出书社"大众}
{"大众_id"大众 : ObjectId("大众59fa71d71fd59c3b2cd908d9"大众),"大众name"大众 : "大众钱钟书"大众,"大众book"大众 : "大众宋诗选注"大众,"大众price"大众 : 99.0,"大众publisher"大众 : "大众人平易近文学出书社"大众}
{"大众_id"大众 : ObjectId("大众59fa71d71fd59c3b2cd908da"大众),"大众name"大众 : "大众钱钟书"大众,"大众book"大众 : "大众谈艺录"大众,"大众price"大众 : 66.0,"大众publisher"大众 : "大众三联书店"大众}
{"大众_id"大众 : ObjectId("大众59fa71d71fd59c3b2cd908db"大众),"大众name"大众 : "大众鲁迅"大众,"大众book"大众 : "大众徘徊"大众,"大众price"大众 : 55.0,"大众publisher"大众 : "大众花城出书社"大众}

如果我想查询每位作者所出的书的总价,操作如下:

var map=function(){emit(this.name,this.price)}
var reduce=function(key,value){return Array.sum(value)}
var options={out:"大众totalPrice"大众}
db.sang_books.mapReduce(map,reduce,options);
db.totalPrice.find()

emit函数主要用来实现分组,接管两个参数,第一个参数表现分组的字段,第二个参数表现要统计的数据,reduce来做详细的数据处置操作,接管两个参数,对应emit办法的两个参数,这里使用了Array中的sum函数对price字段进行自加处置,options中界说了将成果输出的聚拢,届时我们将在这个聚拢中去查询数据,默认环境下,这个聚拢纵然在数据库重启后也会保存,而且保存聚拢中的数据。

查询成果如下:

再好比我想查询每位作者出了几本书,如下:

var map=function(){emit(this.name,1)}
var reduce=function(key,value){return Array.sum(value)}
var options={out:"大众bookNum"大众}
db.sang_books.mapReduce(map,reduce,options);
db.bookNum.find()

查询成果如下:

{
 "大众_id"大众 : "大众曹雪芹"大众,
 "大众value"大众 : 1.0
}
{
 "大众_id"大众 : "大众钱钟书"大众,
 "大众value"大众 : 2.0
}
{
 "大众_id"大众 : "大众鲁迅"大众,
 "大众value"大众 : 2.0
}

将每位作者的书列出来,如下:

var map=function(){emit(this.name,this.book)}
var reduce=function(key,value){return value.join(',')}
var options={out:"大众books"大众}
db.sang_books.mapReduce(map,reduce,options);
db.books.find()

成果如下:

{
 "大众_id"大众 : "大众曹雪芹"大众,
 "大众value"大众 : "大众红楼梦"大众
}
{
 "大众_id"大众 : "大众钱钟书"大众,
 "大众value"大众 : "大众宋诗选注,谈艺录"大众
}
{
 "大众_id"大众 : "大众鲁迅"大众,
 "大众value"大众 : "大众叫嚣,徘徊"大众
}

好比查询每小我售价在¥40以上的书:

var map=function(){emit(this.name,this.book)}
var reduce=function(key,value){return value.join(',')}
var options={query:{price:{$gt:40}},out:"大众books"大众}
db.sang_books.mapReduce(map,reduce,options);
db.books.find()

query表现对查到的聚拢再进行筛选。

成果如下:

{
 "大众_id"大众 : "大众钱钟书"大众,
 "大众value"大众 : "大众宋诗选注,谈艺录"大众
}
{
 "大众_id"大众 : "大众鲁迅"大众,
 "大众value"大众 : "大众徘徊"大众
}

runCommand实现

我们也可以应用runCommand敕令来执行MapReduce。格局如下:

db.runCommand(
    {
     mapReduce: <collection>,
     map: <function>,
     reduce: <function>,
     finalize: <function>,
     out: <output>,
     query: <document>,
     sort: <document>,
     limit: <number>,
     scope: <document>,
     jsMode: <boolean>,
     verbose: <boolean>,
     bypassDocumentValidation: <boolean>,
     collation: <document>
    }
    )

寄义如下:

参数 寄义

mapReduce
表现要操作的聚拢

map
map函数

reduce
reduce函数

finalize
终极处置函数

out
输出的聚拢

query
对成果进行过滤

sort
对成果排序

limit
返回的成果数

scope
设置参数值,在这里设置的值在map、reduce、finalize函数中可见

jsMode
是否将map执行的中央数据由javascript工具转换成BSON工具,默以为false

verbose
是否显示具体的光阴统计信息

bypassDocumentValidation
是否绕过文档验证

collation
其他一些校对

如下操作,表现执行MapReduce操作并对统计的聚拢限定返回条数,限定返回条数之后再进行统计操作,如下:

var map=function(){emit(this.name,this.book)}
var reduce=function(key,value){return value.join(',')}
db.runCommand({mapreduce:'sang_books',map,reduce,out:"大众books"大众,limit:4,verbose:true})
db.books.find()

执行成果如下:

{
 "大众_id"大众 : "大众曹雪芹"大众,
 "大众value"大众 : "大众红楼梦"大众
}
{
 "大众_id"大众 : "大众钱钟书"大众,
 "大众value"大众 : "大众宋诗选注,谈艺录"大众
}
{
 "大众_id"大众 : "大众鲁迅"大众,
 "大众value"大众 : "大众叫嚣"大众
}

小伙伴们看到,鲁迅有一本书不见了,便是由于limit是先限定聚拢返回条数,然后再执行统计操作。

finalize操作表现终极处置函数,如下:

var f1 = function(key,reduceValue){var obj={};obj.author=key;obj.books=reduceValue; return obj}
var map=function(){emit(this.name,this.book)}
var reduce=function(key,value){return value.join(',')}
db.runCommand({mapreduce:'sang_books',map,reduce,out:"大众books"大众,finalize:f1})
db.books.find()

f1第一个参数key表现emit中的第一个参数,第二个参数表现reduce的执行成果,我们可以在f1中对这个成果进行再处置,成果如下:

{
 "大众_id"大众 : "大众曹雪芹"大众,
 "大众value"大众 : {
  "大众author"大众 : "大众曹雪芹"大众,
  "大众books"大众 : "大众红楼梦"大众
 }
}
{
 "大众_id"大众 : "大众钱钟书"大众,
 "大众value"大众 : {
  "大众author"大众 : "大众钱钟书"大众,
  "大众books"大众 : "大众宋诗选注,谈艺录"大众
 }
}
{
 "大众_id"大众 : "大众鲁迅"大众,
 "大众value"大众 : {
  "大众author"大众 : "大众鲁迅"大众,
  "大众books"大众 : "大众叫嚣,徘徊"大众
 }
}

scope则可以用来界说一个在map、reduce和finalize中都可见的变量,如下:

var f1 = function(key,reduceValue){var obj={};obj.author=key;obj.books=reduceValue;obj.sang=sang; return obj}
var map=function(){emit(this.name,this.book)}
var reduce=function(key,value){return value.join(',--'+sang+'--,')}
db.runCommand({mapreduce:'sang_books',map,reduce,out:"大众books"大众,finalize:f1,scope:{sang:"大众haha"大众}})
db.books.find()

执行成果如下:

{
 "大众_id"大众 : "大众曹雪芹"大众,
 "大众value"大众 : {
  "大众author"大众 : "大众曹雪芹"大众,
  "大众books"大众 : "大众红楼梦"大众,
  "大众sang"大众 : "大众haha"大众
 }
}
{
 "大众_id"大众 : "大众钱钟书"大众,
 "大众value"大众 : {
  "大众author"大众 : "大众钱钟书"大众,
  "大众books"大众 : "大众宋诗选注,--haha--,谈艺录"大众,
  "大众sang"大众 : "大众haha"大众
 }
}
{
 "大众_id"大众 : "大众鲁迅"大众,
 "大众value"大众 : {
  "大众author"大众 : "大众鲁迅"大众,
  "大众books"大众 : "大众叫嚣,--haha--,徘徊"大众,
  "大众sang"大众 : "大众haha"大众
 }
}

好了,MongoDB中的MapReduce我们就先说到这里,小伙伴们有问题迎接留言讨论。

总结

以上便是这篇文章的全体内容了,愿望本文的内容对年夜家的进修或者事情具有必定的参考进修代价,假如有疑问年夜家可以留言交流,谢谢年夜家对剧本之家的支撑。

参考材料:

1.《MongoDB权势巨子指南第2版》

2.mongodb mapreduce小试

3.mongoDB--mapreduce用法详解(未找到原始出处)

您可能感兴致的文章:

MongoDB中MapReduce编程模子使用实例Mongodb中MapReduce实现数据聚合办法详解MongoDB中的MapReduce简介MongoDB进修条记之MapReduce使用示例

发表评论

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: