加入收藏 | 设为首页 | 会员中心 | 我要投稿 聊城站长网 (https://www.0635zz.com/)- 智能语音交互、行业智能、AI应用、云计算、5G!
当前位置: 首页 > 服务器 > 系统 > 正文

MongoDB里MapReduce怎么样使用?

发布时间:2023-08-22 15:15:55 所属栏目:系统 来源:
导读:这篇文章主要给大家介绍的是关于在MongoDB中MapReduce的使用,小编认为是比较实用的,因此分享给大家作参考,需要的朋友可以看看,希望对大家学习有帮助。

玩过Hadoop的小伙伴对MapReduce应该不陌生,Map
这篇文章主要给大家介绍的是关于在MongoDB中MapReduce的使用,小编认为是比较实用的,因此分享给大家作参考,需要的朋友可以看看,希望对大家学习有帮助。
 
       玩过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中定义了将结果输出的集合,届时我们将在这个集合中去查询数据,默认情况下,这个集合即使在数据库重启后也会保留,并且保留集合中的数据。
 
       查询结果如下:
 
{
 
 "_id" : "曹雪芹",
 
 "value" : 22.0
 
}
 
{
 
 "_id" : "钱钟书",
 
 "value" : 165.0
 
}
 
{
 
 "_id" : "鲁迅",
 
 "value" : 93.0
 
}
 
       再比如我想查询每位作者出了几本书,如下:
 
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"
 
 }
 
}
 
 

(编辑:聊城站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!