mapreduce实现搜索引擎简单的倒排索引
使用hadoop版本为2.2.0
倒排索引简单的可以理解为全文检索某个词
例如:在a.txt 和b.txt两篇文章分别中查找统计hello这个单词出现的次数,出现次数越多,和关键词的吻合度就越高
现有a.txt内容如下:
hello tom
hello jerry
hello kitty
hello world
hello tom
b.txt内容如下:
hello jerry
hello tom
hello world
在hadoop平台上编写mr代码分析统计各个单词在两个文本中出现的次数
其实也只是WordCount程序的改版而已~
将两个文本上传到hdfs根目录的ii文件夹下(mr直接读取ii文件夹,会读取所有没有以_(下划线)开头的文件)
编写mr代码
首先分析,map输入的格式为
该行偏移量 该行文本
如:
0 hello
我们知道,map的输出之后会根据相同的key来进行合并
而每个单词都不是唯一的,它可能在两个文本中都出现,使用单词作为key的话无法分辨出该单词属于哪个文本
而使用文本名字作为key的话,那么将达到我们原来的目的,因为map的输出就会变成a.txt->单词..单词..单词
这显然不是我们想要的结果
所以map输出的格式应该为
单个单词->所在文本 1
如:
hello->a.txt 1
这里用->作为单词和所在文本的分隔
这样就可以在根据key进行合并的时候不会影响到我们的结果
map代码如下:
public static class MyMapper extends Mapper<LongWritable, Text, Text, Text> { private Text k = new Text();
private Text v = new Text(); protected void map(
LongWritable key,
Text value,
org.apache.hadoop.mapreduce.Mapper<LongWritable, Text, Text, Text>.Context context)
throws java.io.IOException, InterruptedException {
String[] data = value.toString().split(" ");
//FileSplit类从context上下文中得到,可以获得当前读取的文件的路径
FileSplit fileSplit = (FileSplit) context.getInputSplit();
//文件路径为hdfs://hadoop:9000/ii/a.txt
//根据/分割取最后一块即可得到当前的文件名
String[] fileNames = fileSplit.getPath().toString().split("/");
String fileName = fileNames[fileNames.length - 1];
for (String d : data) {
k.set(d + "->" + fileName);
v.set("1");
context.write(k, v);
}
};
}
在map执行完毕之后
我们需要一个combiner来帮助完成一些工作
注意,combiner的输入格式和输出格式是一致的,也就是map的输出格式,否则会出错
再次分析,根据key合并value之后的键值对是这个样子的:
(hello->a.txt,{1,1,1,1,1})
combiner要做的工作就是讲values统计累加
并将key的单词和文本分隔开,将文本名和统计之后的values组合在一起形成新的value
如:
(hello,a.txt->5)
为什么要这么做?
因为在combiner执行完毕之后
还会根据key进行一次value的合并,跟map之后的是一样的
将key相同的value组成一个values集合
如此一来,在经过combiner执行之后,到达reduce的输入就变成了
(hello,{a.txt->5,b.txt->3})
这样的格式,然后在reduce中循环将values输出不就是我们想要的结果了吗~
combiner代码如下:
public static class MyCombiner extends Reducer<Text, Text, Text, Text> { private Text k = new Text();
private Text v = new Text(); protected void reduce(
Text key,
java.lang.Iterable<Text> values,
org.apache.hadoop.mapreduce.Reducer<Text, Text, Text, Text>.Context context)
throws java.io.IOException, InterruptedException {
//分割文件名和单词
String[] wordAndPath = key.toString().split("->");
//统计出现次数
int counts = 0;
for (Text t : values) {
counts += Integer.parseInt(t.toString());
}
//组成新的key-value输出
k.set(wordAndPath[0]);
v.set(wordAndPath[1] + "->" + counts);
context.write(k, v);
};
}
接下来reduce的工作就简单了
代码如下:
public static class MyReducer extends Reducer<Text, Text, Text, Text> { private Text v = new Text(); protected void reduce(
Text key,
java.lang.Iterable<Text> values,
org.apache.hadoop.mapreduce.Reducer<Text, Text, Text, Text>.Context context)
throws java.io.IOException, InterruptedException {
String res = "";
for (Text text : values) {
res += text.toString() + "\r";
}
v.set(res);
context.write(key, v);
};
}
main方法代码:
public static void main(String[] args) throws Exception {
Configuration conf = new Configuration();
FileSystem fs = FileSystem.get(conf);
Path inPath = new Path("hdfs://hadoop:9000" + args[0]);
Path outPath = new Path("hdfs://hadoop:9000" + args[1]);
if (fs.exists(outPath)) {
fs.delete(outPath, true);
}
Job job = Job.getInstance(conf);
job.setJarByClass(InverseIndex.class); FileInputFormat.setInputPaths(job, inPath);
job.setInputFormatClass(TextInputFormat.class); job.setMapperClass(MyMapper.class);
job.setMapOutputKeyClass(Text.class);
job.setMapOutputValueClass(Text.class); job.setCombinerClass(MyCombiner.class); job.setReducerClass(MyReducer.class);
job.setOutputKeyClass(Text.class);
job.setOutputValueClass(Text.class); FileOutputFormat.setOutputPath(job, outPath);
job.setOutputFormatClass(TextOutputFormat.class); job.waitForCompletion(true);
}
在hadoop上运行jar包执行结果如图:
初学hadoop,仅作笔记之用,其中如有错误望请告知^-^
mapreduce实现搜索引擎简单的倒排索引的更多相关文章
- [Search Engine] 搜索引擎技术之倒排索引
倒排索引是搜索引擎中最为核心的一项技术之一,可以说是搜索引擎的基石.可以说正是有了倒排索引技术,搜索引擎才能有效率的进行数据库查找.删除等操作. 1. 倒排索引的思想 倒排索引源于实际应用中需要根据属 ...
- ES搜索引擎-简单入门
基本概念: 索引Index es吧数据放到一个或者多个索引中,如果用关系型数据库模型对比,索引的地位与数据库实例(db)相当.索引存放和读取的基本单元是文档(document).es内部使用的是apa ...
- 国内最全最详细的hadoop2.2.0集群的MapReduce的最简单配置
简介 hadoop2的中的MapReduce不再是hadoop1中的结构已经没有了JobTracker,而是分解成ResourceManager和ApplicationMaster.这次大变革被称为M ...
- mapreduce on yarn简单内存分配解释
关于mapreduce程序运行在yarn上时内存的分配一直是一个让我蒙圈的事情,单独查任何一个资料都不能很好的理解透彻.于是,最近查了大量的资料,综合各种解释,终于理解到了一个比较清晰的程度,在这里将 ...
- [How to] MapReduce on HBase ----- 简单二级索引的实现
1.简介 MapReduce计算框架是二代hadoop的YARN一部分,能够提供大数据量的平行批处理.MR只提供了基本的计算方法,之所以能够使用在不用的数据格式上包括HBase表上是因为特定格式上的数 ...
- Hadoop(11)-MapReduce概述和简单实操
1.MapReduce的定义 2.MapReduce的优缺点 优点 缺点 3.MapReduce的核心思想 4.MapReduce进程 5.常用数据序列化类型 6.MapReduce的编程规范 用户编 ...
- MapReduce原理及简单实现
MapReduce是Google在2004年发表的论文<MapReduce: Simplified Data Processing on Large Clusters>中提出的一个用于分布 ...
- MapReduce应用案例--简单排序
1. 设计思路 在MapReduce过程中自带有排序,可以使用这个默认的排序达到我们的目的. MapReduce 是按照key值进行排序的,我们在Map过程中将读入的数据转化成IntWritable类 ...
- MapReduce应用案例--简单的数据去重
1. 设计思路 去重,重点就是无论某个数据在文件中出现多少次,最后只是输出一次就可以. 根据这一点,我们联想到在reduce阶段数据输入形式是 <key, value list>,只要是k ...
随机推荐
- scrapy的CrawlSpider使用
1.创建项目 我这里的项目名称为scrapyuniversal,然后我创建在D盘根目录.创建方法如下 打开cmd,切换到d盘根目录.然后输入以下命令: scrapy startproject scra ...
- 【bzoj3261】最大异或和
就是一个可持久化Trie....... #include<bits/stdc++.h> #define N 600005 using namespace std; inline int r ...
- 【 Tomcat 】tomcat8.0 基本参数调优配置
1.优化内核及TCP连接: fs.file-max = # 系统文件描述符总量 net.ipv4.ip_local_port_range = # 打开端口范围 net.ipv4.tcp_max_tw_ ...
- krpano--控制热点跳转到场景的指定视角
krpano课堂(肥宗) · 2015-07-13 19:32 有这么一种情况,假设我们用三个场景,这三个场景恰好是一条街道的同一方向的三个拍摄点.如上图. 我们可以通过设置A.B.C三个场景中的vi ...
- python中进程池的应用
#原创,转载请联系 假设我们写的一个程序需要运行100个子进程的时候,那么写程序时,不可能循环创建销毁100个进程吧?进程的创建与销毁是很耗系统的资源的. 进程池的作用就体现出来了. 进程池可以控制进 ...
- SpringMVC框架入门配置 IDEA下搭建Maven项目(zz)
SpringMVC框架入门配置 IDEA下搭建Maven项目 这个不错哦 http://www.cnblogs.com/qixiaoyizhan/p/5819392.html
- hdu 1423(LCS+LIS)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1423 好坑啊..还有公共串为0时的特殊判断,还有格式错误..看Discuss看知道除了最后一组测试数据 ...
- 使用 mybatis和oracle 数据库出现的问题
mybatis 官网教程 http://www.mybatis.org/mybatis-3/zh/dynamic-sql.html 出现 Could not set parameters for ma ...
- 团队开发中git分支的使用
1.Github上保持两个分支:master和develop. master是主分支,对项目进行tag或发布版本等操作,都必须在该分支上进行.最好设为不可提交只能合并的. develop是开发分支,从 ...
- 安装XHProf分析PHP性能瓶颈(原创)
废话不多说,直接上代码 ,手动滑稽.o(╯□╰)o 如果已解决您的问题,请在文章底部点击下关注,非常感谢. 下面是LINUX命令行 $ wget http://pecl.php.net/get/x ...