- A+
前言
玩过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使用示例