文档章节

MapReduce初探之一~~基于Mongodb实现标签统计

zhiweiofli
 zhiweiofli
发布于 2013/03/06 09:57
字数 1033
阅读 2317
收藏 80

MapReduce 是一种编程模型,是 Google 提出的一种软件架构,主要应用于分布式系统上。Google对其原始的定义是“ MapReduce is a framework for computing certain kinds of distributable problems using a large number of computers (nodes), collectively referred to as a cluster.”

可见MapReduce主要为集群分布式计算而诞生的,顶顶大名的分布式框架Hadoop就是MapReduce的一种实现。其中心思想是Map(映射)函数和Reduce(化简)函数,我的简单理解就是先将问题按照一定的规律,一一细分并映射到列表中,然后对那些列表进行适当的合并,从而得出想要的结果,大致的工作流见于下图: 

咋一看,怎么就是分布式计算的原理图解了?论道分布式计算,就扯远了,回到主题上,这次是讨论如何利用MapReduce的思想,实现Blog文章标签的统计!

按照传统的关系数据库设计,统计标签,无非就是建一张标签表,我们姑且叫左Tb_tags,大致的结构就是id和value,然后关联id到Blog表的外键上。恩,不差错。可是这次,NodeBlog的数据库用的可是Mongodb哦,难道照搬即可?

我们先看看在mongodb下,Blog表是如何描述的:

var BlogScheme = new db.Schema({
    title : String,
    desc : String,
    author : String,
    body : String,
    tags : [String],
    count: { type:Number, default:0 },
    hidden : { type: Boolean, default: false },
    date : { type: Date, default: Date.now },
    comments : [{ img: String, name: String, body: String, date: Date }],
    meta : {
        votes: Number,
        favs:  Number
    }
});

按照mongodb的设计,每篇Blog都是整篇存储的,与其它表基本没有关联,这也是NoSQL的精髓啊!但是这样子,我们该如何去统计Blog的标签tag呢?

办法有几个:1、遍历查询全部的Blog,取出Blog的实体,然后对其中的tags字段进行统计;(这个简单,绝对可行,只是效率就...)

                     2、 对1中的方法采用多线程进行查询,然后同步共享的数据;(这个在实现与现今的硬件上,理论绝对比方法1高效,但是实现的难度,特别是数据的同步那块就...)

                     3、让MapReduce来帮帮忙吧!

MapReduce中,Map函数和Reduce函数是交给用户实现的,这两个函数定义了任务本身。

  • Map函数:接受一个键值对(key-value pair),产生一组中间键值对。MapReduce框架会将map函数产生的中间键值对里键相同的值传递给一个reduce函数。
  • Reduce函数:接受一个键,以及相关的一组值,将这组值进行合并产生一组规模更小的值(通常只有一个或零个值)。

对照我们的需求,统计Blog中的tags,那么Map函数应该处理的是:记录tag出现的次数,这个越小越好;然后Reduce函数对Map函数产生的数据进行合并,并返回单一的结果,即是某个tag出现的总次数!下面来一个实例说明:

/**
 * 统计Blog中标签出现的次数,采用MapReduce进行实时计算
 * @param callback --> result: _id(tag name), value(occupied count)
 */
exports.tagStatistical = function(callback){
    var o = {};
    o.map = function () {
        this.tags.forEach(function(z){  //z即是具体的某个tag了
            emit(z,1);                    //对某个tag出现一次就计数一次
        });
    }
    o.reduce = function (k, values) {
        var total=0;
        for(var i=0;i<values.length;i++){
            total += values[i];
        }
        return total;
    }
    Blog.mapReduce(o, function (err, results) {
        if(err) {
            console.log("mapReduce err:"+err);
        }
        console.log(results);
        callback(results);
    })
}


最后我们通过callback函数获得的result事实上就是(tag,count)的Map了,这是如何实现的?这点,就有赖于Mongodb的高级特性了,Mongodb对于 MapReduce 是骨子里支持的,因而这种运算的效率是有保障的!难怪Mongodb的掌门人叫嚣:不是Mongodb不行,是你们不懂Mongodb!  

总结一下,尽管这篇Blog讲得有点乱,但是主要还是想讲清楚MapReduce的思想! MapReduce的实现五花八门,但是其中心思想~map和reduce才是我们必须理解和掌握的!


本文由zhiweiofli编辑发布,转载请注明出处,点击,谢谢。

© 著作权归作者所有

zhiweiofli

zhiweiofli

粉丝 11
博文 9
码字总数 9323
作品 0
广州
程序员
私信 提问
加载中

评论(5)

zhiweiofli
zhiweiofli 博主

引用来自“Grrrr”的评论

引用来自“zhiweiofli”的评论

引用来自“Grrrr”的评论

不错。介绍了map reduce. 不过现在文章和标签的设计都是反向连接。

本人初学,求指导

呵呵,谈不上指导。map reduce已经讲的很清楚了。不过用在标签这个例子不是很好,现在文章和标签的流行设计是反向连接,即文章里面不包含任何标签的信息。而标签里面包含它对应的文章地址,当对一个文章贴标签时,往这个标签添加这个文章的url地址就可以了。类似Lucene关键字的做法。

哦,明白了,谢谢
Grrrr
Grrrr

引用来自“zhiweiofli”的评论

引用来自“Grrrr”的评论

不错。介绍了map reduce. 不过现在文章和标签的设计都是反向连接。

本人初学,求指导

呵呵,谈不上指导。map reduce已经讲的很清楚了。不过用在标签这个例子不是很好,现在文章和标签的流行设计是反向连接,即文章里面不包含任何标签的信息。而标签里面包含它对应的文章地址,当对一个文章贴标签时,往这个标签添加这个文章的url地址就可以了。类似Lucene关键字的做法。
zhiweiofli
zhiweiofli 博主

引用来自“Grrrr”的评论

不错。介绍了map reduce. 不过现在文章和标签的设计都是反向连接。

本人初学,求指导
Grrrr
Grrrr
不错。介绍了map reduce. 不过现在文章和标签的设计都是反向连接。
EDIAGD
EDIAGD
简单明了
MongoDB能做稍微复杂一点的统计吗?

比如类似 select sum(*) ,userType from user group by userType 这样的统计. mongodb的groupby必须有主键, 遇到select sum(*) from user就没辙了 而内置的mapreduce官方说不是实时的,不建议...

零点三六
2012/02/13
5.1K
3
基于 MongoDB 分布式存储进行 MapReduce 并行查询

之前的文章中介绍了如何基于Mongodb进行关系型数据的分布式存储,有了存储就会牵扯到查询。虽然用普通的方式也可以进行查询,但今天要介绍的是如何使用MONGODB中提供的MapReduce功能进行查询...

小编辑
2010/11/25
1K
0
MongoDB工具MagicMongoDBTool使用介绍

MagicMongoDBTool工具是一款MongoDB的数据库管理工具,用来进行简单的数据库管理工作。此工具为国人开发,项目地址:MagicMongoDBTool,目前作者已经完成基本功能开发,借NoSQLFan向各位Mon...

红薯
2011/11/12
1K
2
MongoDB高级一点点的操作

在MongoDB数据库中常见的聚合操作有:count,distinct,group,mapReduce。现在将它们一一的记录下来: 一、count操作 这个操作顾名思义就是达到统计的效果啦,用来统计符合某一种查询条件的...

BravoZu
2014/01/21
1K
0
MongoDB工具MagicMongoDBTool使用介绍

MagicMongoDBTool工具是一款MongoDB的数据库管理工具,用来进行简单的数据库管理工作。此工具为国人开发,项目地址:MagicMongoDBTool,目前作者已经完成基本功能开发,借NoSQLFan向各位Mon...

鉴客
2012/04/25
2.4K
1

没有更多内容

加载失败,请刷新页面

加载更多

一、docker 入坑(win10和Ubuntu 安装)

前言 终究还是绕不过去了,要学的知识真的是太多了,好在我们还有时间,docker 之前只闻其声,不曾真正的接触过,现在docker 越来越火,很多公司也都开始使用了。所以对于我们程序员而言,又...

quellanan2
15分钟前
4
0
AutoCompleteTextView

小技巧按菜单键 当菜单打开之前会调用onMenuOpened(int featereId,Menu menu),可以重写这个方法,弹出对话框或者Popmenu 再布局中添加控件AutoCompleteTextView. <AutoCompleteTextVie...

逆天游云
18分钟前
4
0
谷歌软件商店:推出5美元会员 可用数百个软件

腾讯科技讯,谷歌和苹果是全球两大智能手机操作系统的运营者,两家公司旗下分别拥有占据行业垄断地位的谷歌软件商店和苹果软件商店。据外媒最新消息,手机软件商店的商业模式正在发生一些变化...

linuxCool
40分钟前
3
0
RocketMQ 多副本前置篇:初探raft协议

Raft协议是分布式领域解决一致性的又一著名协议,主要包含Leader选举、日志复制两个部分。 温馨提示: 本文根据raft官方给出的raft动画进行学习,其动画展示地址:http://thesecretlivesofda...

中间件兴趣圈
40分钟前
3
0
elasticsearch 6.8.0 添加认证

1. 修改elasticsearch-6.8.0/config/elasticsearch.yml 最后添加一行:xpack.security.enabled: true 2. 初始化用户和密码 ./bin/elasticsearch-setup-passwords interactive 我这里初始化为......

coord
42分钟前
4
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部