MongoDB中的MapReduce介绍与使用
一、简介
在用MongoDB查询返回的数据量很大的情况下,做一些比较复杂的统计和聚合操作做花费的时间很长的时候,可以用MongoDB中的MapReduce进行实现
MapReduce是个非常灵活和强大的数据聚合工具。它的好处是可以把一个聚合任务分解为多个小的任务,分配到多服务器上并行处理。MongoDB也提供了MapReduce,当然查询语肯定是JavaScript。
MongoDB中的MapReduce主要有以下几阶段:
Map:把一个操作Map到集合中的每一个文档
Shuffle: 根据Key分组对文档,并且为每个不同的Key生成一系列(>=1个)的值表(List of values)。
Reduce: 处理值表中的元素,直到值表中只有一个元素。然后将值表返回到Shuffle过程,循环处理,直到每个Key只对应一个值表,并且此值表中只有一个元素,这就是MR的结果。
Finalize:此步骤不是必须的。在得到MR最终结果后,再进行一些数据“修剪”性质的处理。
MongoDB中使用emit函数向MapReduce提供Key/Value对。
Reduce函数接受两个参数:Key,emits. Key即为emit函数中的Key。 emits是一个数组,它的元素就是emit函数提供的Value。
Reduce函数的返回结果必须要能被Map或者Reduce重复使用,所以返回结果必须与emits中元素结构一致。
Map或者Reduce函数中的this关键字,代表当前被Mapping文档。
二、介绍
- db.runCommand({
- mapreduce:<collection>,
- map:<mapfunction>,
- reduce:<reducefunction>,
- [,query:<query filter object>]
- [,sort:<sorts the input objects using this key.Useful for optimization,like sorting by the emit key for fewer reduces>]
- [,limit:<number of objects to return from collection>]
- [,out:<see output options below>]
- [,keeptemp:<true|false>]
- [,finalize:<finalizefunction>]
- [,scope:<object where fields go into javascript global scope>]
- [, jsMode : boolean,default true]
- [,verbose:true]
- });
参数说明:
Mapreduce:要操作的目标集合
Map:映射函数(生成键值对序列,作为reduce函数参数)
Reduce:统计函数
Query:目标记录过滤
Sort:目标记录排序
Limit:限制目标记录数量
Out:统计结果存放集合(不指定使用临时集合,在客户端断开后自动删除)
Keeptemp:是否保留临时集合
Finalize:最终处理函数(对reduce返回结果进行最终整理后存入结果集合)
Scope:向map、reduce、finalize导入外部变量
jsMode说明:为false时 BSON-->JS-->map-->BSON-->JS-->reduce-->BSON,可处理非常大的mapreduce,为true时 BSON-->js-->map-->reduce-->BSON
Verbose:显示详细的时间统计信息
行查询的步骤
MapReduce对指定的集合Collection进行查询
对A的结果集进行mapper方法采集
对B的结果执行finalize方法处理
最终结果集输出到临时Collection中
断开连接,临时Collection删除或保留
需要注意的
以下是来自文档的图,可以清楚的说明 Map-Reduce 的执行过程。
In this map-reduce operation, MongoDB applies the map phase to each input document (i.e. the documents in the collection that match the query condition). The map function emits key-value pairs. For those keys that have multiple values, MongoDB applies the reduce phase, which collects and condenses the aggregated data. MongoDB then stores the results in a collection. Optionally, the output of the reduce function may pass through a finalize function to further condense or process the results of the aggregation.
All map-reduce functions in MongoDB are JavaScript and run within the
mongod
process. Map-reduce operations take the documents of a single collection as the input and can perform any arbitrary sorting and limiting before beginning the map stage.mapReduce
can return the results of a map-reduce operation as a document, or may write the results to collections. The input and the output collections may be sharded.
NOTE
For most aggregation operations, the Aggregation Pipeline provides better performance and more coherent interface. However, map-reduce operations provide some flexibility that is not presently available in the aggregation pipeline.
Map-Reduce 的执行过程是先 map
然后 reduce
么?仔细再看一遍上文的图,不是每次 map
都有 reduce
的!如果 map
的结果不是数组,mongodb 就不会执行 reduce
。很合理的处理逻辑。
对于 map
到的数据,如果在 reduce
时希望做统一的处理,一定会发现数据结果是不完整的。
三、查询分析
测试数据:
- > db.test.find()
- { "_id" : ObjectId("5a1d45ab893253f4d2e4bf91"), "name" : "yy1", "age" : "22" }
- { "_id" : ObjectId("5a1d45b1893253f4d2e4bf92"), "name" : "yy2", "age" : "23" }
- { "_id" : ObjectId("5a1d45c5893253f4d2e4bf93"), "name" : "yy3", "age" : "24" }
- { "_id" : ObjectId("5a1d45d4893253f4d2e4bf94"), "name" : "yy5", "age" : "25" }
- { "_id" : ObjectId("5a1d45f7893253f4d2e4bf95"), "name" : "yy6", "age" : "26" }
- { "_id" : ObjectId("5a1d45ff893253f4d2e4bf96"), "name" : "yy4", "age" : "25" }
1、查询年龄大于23岁的
map:
- var m = function(){if(this.age > 23) emit(this.age,{name:this.name})};
reduce:
- var r = function(key,values){return JSON.stringify(values);}
或者:
- var r = function(key,values){ var ret={names:values};return ret;}
生成结果集:
- var res = db.runCommand({mapreduce:"test",map:m,reduce:r,out:"emp_res"})
查询:
- > db.emp_res.find()
- { "_id" : "24", "value" : { "name" : "yy3" } }
- { "_id" : "25", "value" : "[{\"name\":\"yy5\"},{\"name\":\"yy4\"}]" }
- { "_id" : "26", "value" : { "name" : "yy6" } }
或者:
- > db.emp_res.find()
- { "_id" : "24", "value" : { "name" : "yy3" } }
- { "_id" : "25", "value" : { "names" : [ { "name" : "yy5" }, { "name" : "yy4" } ] } }
- { "_id" : "26", "value" : { "name" : "yy6" } }
最后,还可以编写finalize函数对reduce的返回值做最后处理:
- var f=function(key,rval){ if(key==24){ rval.msg="do somethings";} return rval }
生成结果集:
- > var f=function(key,rval){ if(key==24){ rval.msg="do somethings";} return rval }
- > db.emp_res.find()
- { "_id" : "24", "value" : { "name" : "yy3", "msg" : "do somethings" } }
- { "_id" : "25", "value" : { "names" : [ { "name" : "yy5" }, { "name" : "yy4" } ] } }
- { "_id" : "26", "value" : { "name" : "yy6" } }
- >
2、过滤出来age=25的
方法1:
- > var m = function(){ emit(this.age,{name:this.name})};
- > var r = function(key,values){ var ret={names:values};return ret;}
- > var res = db.runCommand({mapreduce:"test",map:m,reduce:r,finalize:f,query:{age:"25"},out:"emp_res"})
- > db.emp_res.find()
- { "_id" : "25", "value" : { "names" : [ { "name" : "yy5" }, { "name" : "yy4" } ] } }
方法2:
- > var m = function(){ emit(this.age,{p:[this.name]})};
- > var r = function(key, values) {
- var ret = {p:[]};
- for(var i = 0; i < values.length; i++){
- ret.p.push(values[i].p[0]);
- }
- return ret;
- };
- > var res = db.runCommand({mapreduce:"test",map:m,reduce:r,finalize:f,query:{age:"25"},out:"emp_res"})
方法3:
- > var m = function() {
- emit(this.age, {name:[this.name]});
- };
- > var r = func tion(key, values) {
- var ret = {locs:[]}
- for(var i = 0; i < values.length; i++){
- ret.locs.push(values[i].locs[0]);
- }
- return ret;
- };
- > var res = db.runCommand({mapreduce:"test",map:map,reduce:reduce,finalize:f,query:{age:"25"},out:"emp_res"})
这个过程中遇到很多坑,需要多练习,多debug
参考
MongoDB中的MapReduce介绍与使用的更多相关文章
- 【转载】MongoDB中的MapReduce 高级操作介绍
转载自残缺的孤独 1.概述 MongoDB中的MapReduce相当于关系数据库中的group by.使用MapReduce要实现两个函数Map和Reduce函数.Map函数调用emit(key,va ...
- MongoDB中通过MapReduce实现合计Sum功能及返回格式不一致问题分析
建立下述测试数据,通过MapReduce统计每个班级学生数及成绩和. 代码如下: public string SumStudentScore() { var collection = _dataBas ...
- MongoDB中MapReduce介绍与使用
一.简介 在用MongoDB查询返回的数据量很大的情况下,做一些比较复杂的统计和聚合操作做花费的时间很长的时候,可以用MongoDB中的MapReduce进行实现 MapReduce是个非常灵活和强大 ...
- MongoDB中聚合工具Aggregate等的介绍与使用
Aggregate是MongoDB提供的众多工具中的比较重要的一个,类似于SQL语句中的GROUP BY.聚合工具可以让开发人员直接使用MongoDB原生的命令操作数据库中的数据,并且按照要求进行聚合 ...
- MongoDB中mapReduce的使用
MongoDB中mapReduce的使用 制作人:全心全意 mapReduce的功能和group by的功能类似,但比group by处理的数据量更大 使用示例: var map = function ...
- MongoDB中4种日志的详细介绍
前言 任何一种数据库都有各种各样的日志,MongoDB也不例外.MongoDB中有4种日志,分别是系统日志.Journal日志.oplog主从日志.慢查询日志等.这些日志记录着MongoDB数据库不同 ...
- 浅析mongodb中group分组
这篇文章主要介绍了浅析mongodb中group分组的实现方法及示例,非常的简单实用,有需要的小伙伴可以参考下. group做的聚合有些复杂.先选定分组所依据的键,此后MongoDB就会将集合依据选定 ...
- 基于MongoDB分布式存储进行MapReduce并行查询
中介绍了如何基于Mongodb进行关系型数据的分布式存储,有了存储就会牵扯到查询.虽然用普通的方式也可以进行查询,但今天要介绍的是如何使用MONGODB中提供的MapReduce功能进行查询. ...
- MongoDB实战指南(五):MongoDB中的聚集分析
聚集操作是对数据进行分析的有效手段.MongoDB主要提供了三种对数据进行分析计算的方式:管道模式聚集分析,MapReduce聚集分析,简单函数和命令的聚集分析. 1. 管道模式进行聚集 这里所说的管 ...
随机推荐
- git学习整理(1)git clone 理解
1.git clone 的理解 git clone默认会把远程仓库整个给clone下来 ,只能clone远程库的master分支并在本地默认创建一个master分支 ,无法clone所有分支,若想要其 ...
- jscodeshift 简易教程
本文首发于 https://github.com/whxaxes/blog/issues/10 背景 jscodeshift 是 fb 出的一个 codemod toolkit,基于 recast 这 ...
- 极化码之tal-vardy算法(3)
考完驾照,回来填坑 /doge/doge 前两节分别介绍了tal算法中的合并函数和信道操作两个部分,我们将高斯信道的应用放在最后一节来介绍. 在之前的介绍中,我们一直在一个前提下进行讨论--即输入字符 ...
- Emgu.CV(一)
由于这块的知识不少,会分好几期写完 什么是OpenCV? OpenCV是一个基于(开源)发行的跨平台计算机视觉库,可以运行在Linux.Windows和Mac OS操作系统上.它轻量级而且高效--由一 ...
- flume自定义Source(taildirSource),自定义Sink(数据库),开发完整步骤
一.flume简单了解推荐网站(简介包括简单案例部署): http://www.aboutyun.com/thread-8917-1-1.html 二.我的需求是实现从ftp目录下采集数据,目录下文件 ...
- 跟着弦哥学人工智能2—HAND-CRAFTED RULES实现的人工智能及其缺陷
隔壁有个妹纸喷我,好高兴....给她回复了下 哎呀,没想到是个妹纸,其实我就随便那么一说,没合计妹纸还专门写个檄文声讨我,受宠若惊其实你的评论一看就比较专业,所以我就去你博客大概扫了一眼,发现个大问 ...
- [IR] Concept Search and LDA
重要的是通过实践更深入地了解贝叶斯思想,先浅浅地了解下LDA. From: http://blog.csdn.net/huagong_adu/article/details/7937616/ 传统方法 ...
- 使用Git 本地代码提交到 GitHub
第一步:下载Git 工具 在官网下载 https://git-scm.com/ 第二部:注册官方账号 创建一个村代码的仓库 注册地址https://github.com/ 第三部:本地代码 通过Git ...
- [Bayesian] “我是bayesian我怕谁”系列 - Continuous Latent Variables
打开prml and mlapp发现这部分目录编排有点小不同,但神奇的是章节序号竟然都为“十二”. prml:pca --> ppca --> fa mlapp:fa --> pca ...
- PyQt5安装目录中找不到designer.exe与pyrcc5.exe
我安装的是PyQt5的5.9版本,在安装目录下找不到designer.exe文件.在摸索一段后发现5.9版本对库文件和相关的开发工具是分开发布的.QtDesigner是在pyqt5-tools的包里. ...