hadoop实现倒排索引
hadoop实现倒排索引
本文用hadoop实现倒排索引算法,用基本的分两步完成,不使用combine
第一步
读入文档,统计文档中各个单词的个数,与word count类似,但这里把word-filename组合起来作为一个key,并把中间结果写到磁盘中
InverseIndexStepTwo.java
package postlisting;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Job;
import org.apache.hadoop.mapreduce.Mapper;
import org.apache.hadoop.mapreduce.Reducer;
import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
import org.apache.hadoop.mapreduce.lib.input.FileSplit;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;
import org.apache.hadoop.util.StringUtils;
import java.io.IOException;
/**
* 倒排索引步骤一,先做word count,不过现在的key是word-filename
*/
public class InverseIndexStepOne {
public static class StepOneMapper extends Mapper<LongWritable, Text, Text, LongWritable>{
@Override
protected void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException {
String line = value.toString();
// 切分出各个单词
String[] fields = line.split(" ");
// 获取文件切片
FileSplit inputsplit = (FileSplit)context.getInputSplit();
// 获取文件名
String filename = inputsplit.getPath().getName();
// 计数hello-->a.txt 1
for(String field: fields){
context.write(new Text(field+"-->"+filename), new LongWritable(1));
}
}
}
public static class StepOneReducer extends Reducer<Text, LongWritable, Text, LongWritable>{
@Override
protected void reduce(Text key, Iterable<LongWritable> values, Context context) throws IOException, InterruptedException {
long counter = 0;
for (LongWritable value: values){
counter += value.get();
}
context.write(key, new LongWritable(counter));
}
}
public static void main(String[] args) throws IOException, ClassNotFoundException, InterruptedException {
Configuration conf = new Configuration();
Job job = Job.getInstance(conf);
job.setJarByClass(InverseIndexStepOne.class);
job.setMapperClass(StepOneMapper.class);
job.setReducerClass(StepOneReducer.class);
job.setMapOutputKeyClass(Text.class);
job.setMapOutputValueClass(LongWritable.class);
job.setOutputKeyClass(Text.class);
job.setOutputValueClass(LongWritable.class);
// 检查输出文件夹是否已存在,如果存在先删除
// 本地测试
Path output = new Path("res/words/output/step1");
FileSystem fs = FileSystem.get(conf);
if(fs.exists(output)){
fs.delete(output, true);
}
FileInputFormat.setInputPaths(job, new Path("res/words/input/"));
FileOutputFormat.setOutputPath(job, output);
System.out.println(job.waitForCompletion(true));
}
}
输出结果
hello-->a.txt 2
hello-->b.txt 2
hello-->c.txt 2
jerry-->a.txt 1
jerry-->b.txt 3
jerry-->c.txt 1
tom-->a.txt 3
tom-->b.txt 1
tom-->c.txt 1
第二步
读取上一步的中间结果,解析并合并
InverseIndexStepOne.java
package postlisting;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Job;
import org.apache.hadoop.mapreduce.Mapper;
import org.apache.hadoop.mapreduce.Reducer;
import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;
import java.io.IOException;
public class InverseIndexStepTwo {
public static class StepTwoMapper extends Mapper<LongWritable, Text, Text, Text> {
@Override
protected void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException {
String line = value.toString();
// hello-->a.txt 1
String[] fields = line.split("\t");
String[] wordAndFileName = fields[0].split("-->");
String word = wordAndFileName[0];
String fileName = wordAndFileName[1];
long count = Long.parseLong(fields[1]);
// <hello, a.txt-->3>
context.write(new Text(word), new Text(fileName + "-->" + count));
}
}
public static class StepTwoReducer extends Reducer<Text, Text, Text, Text>{
@Override
protected void reduce(Text key, Iterable<Text> values, Context context) throws IOException, InterruptedException {
// 拿到的数据<hello, a.txt-->3, a.txt-->4,...>
StringBuilder result = new StringBuilder();
for (Text value:values){
result.append(" ").append(value);
}
context.write(key, new Text(result.toString()));
}
}
public static void main(String[] args) throws IOException, ClassNotFoundException, InterruptedException {
Configuration conf = new Configuration();
Job job = Job.getInstance(conf);
job.setJarByClass(InverseIndexStepTwo.class);
job.setMapperClass(StepTwoMapper.class);
job.setReducerClass(StepTwoReducer.class);
job.setMapOutputKeyClass(Text.class);
job.setMapOutputValueClass(Text.class);
job.setOutputKeyClass(Text.class);
job.setOutputValueClass(Text.class);
// 检查输出文件夹是否已存在,如果存在先删除
Path output = new Path("res/words/output/step2");
FileSystem fs = FileSystem.get(conf);
if(fs.exists(output)){
fs.delete(output, true);
}
FileInputFormat.setInputPaths(job, new Path("res/words/output/step1/"));
FileOutputFormat.setOutputPath(job, output);
System.out.println(job.waitForCompletion(true));
}
}
输出结果
hello c.txt-->2 b.txt-->2 a.txt-->2
jerry c.txt-->1 b.txt-->3 a.txt-->1
tom c.txt-->1 b.txt-->1 a.txt-->3
小结
虽然用combine可以节省代码,但感觉分开写更加灵活,写个shell脚本组织一下就好,Map Reduce的强大之处也在与它的自由组合。
hadoop实现倒排索引的更多相关文章
- Hadoop之倒排索引
前言: 从IT跨度到DT,如今的数据每天都在海量的增长.面对如此巨大的数据,如何能让搜索引擎更好的工作呢?本文作为Hadoop系列的第二篇,将介绍分布式情况下搜索引擎的基础实现,即“倒排索引”. 1. ...
- hadoop学习笔记之倒排索引
开发工具:eclipse 目标:对下面文档phone_numbers进行倒排索引: 13599999999 1008613899999999 12013944444444 13800138000137 ...
- hadoop倒排索引
1.前言 学习hadoop的童鞋,倒排索引这个算法还是挺重要的.这是以后展开工作的基础.首先,我们来认识下什么是倒拍索引: 倒排索引简单地就是:根据单词,返回它在哪个文件中出现过,而且频率是多少的结果 ...
- Hadoop 倒排索引
倒排索引是文档检索系统中最常用的数据结构,被广泛地应用于全文搜索引擎.它主要是用来存储某个单词(或词组)在一个文档或一组文档中存储位置的映射,即提供了一种根据内容来查找文档的方式.由于不是根据文档来确 ...
- Hadoop学习笔记(8) ——实战 做个倒排索引
Hadoop学习笔记(8) ——实战 做个倒排索引 倒排索引是文档检索系统中最常用数据结构.根据单词反过来查在文档中出现的频率,而不是根据文档来,所以称倒排索引(Inverted Index).结构如 ...
- Hadoop案例(四)倒排索引(多job串联)与全局计数器
一. 倒排索引(多job串联) 1. 需求分析 有大量的文本(文档.网页),需要建立搜索索引 xyg pingping xyg ss xyg ss a.txt xyg pingping xyg pin ...
- hadoop学习第三天-MapReduce介绍&&WordCount示例&&倒排索引示例
一.MapReduce介绍 (最好以下面的两个示例来理解原理) 1. MapReduce的基本思想 Map-reduce的思想就是“分而治之” Map Mapper负责“分”,即把复杂的任务分解为若干 ...
- Hadoop实战-MapReduce之倒排索引(八)
倒排索引 (就是key和Value对调的显示结果) 一.需求:下面是用户播放音乐记录,统计歌曲被哪些用户播放过 tom LittleApple jack YesterdayO ...
- Hadoop MapReduce编程 API入门系列之倒排索引(二十四)
不多说,直接上代码. 2016-12-12 21:54:04,509 INFO [org.apache.hadoop.metrics.jvm.JvmMetrics] - Initializing JV ...
随机推荐
- windows上编译boost库
要用xx库,编译boost时就指定--with-xx.例如: # 下载并解压boost_1.58 # 进入boost_1.58目录 bjam.exe toolset=msvc-14.0 --build ...
- 一脸懵逼学习Nginx及其安装,Tomcat的安装
1:Nginx的相关概念知识: 1.1:反向代理: 反向代理(Reverse Proxy)方式是指以代理服务器来接受internet上的连接请求,然后将请求转发给内部网络上的服务器,并将从服务器上得到 ...
- WebApi接口返回值不困惑:返回值类型详解
前言:已经有一个月没写点什么了,感觉心里空落落的.今天再来篇干货,想要学习Webapi的园友们速速动起来,跟着博主一起来学习吧.作为程序猿,我们都知道参数和返回值是编程领域不可分割的两大块,此前分享了 ...
- scrapy下载图片报[scrapy.downloadermiddlewares.robotstxt] DEBUG: Forbidden by robots.txt:错误
本文转自:http://blog.csdn.net/zzk1995/article/details/51628205 先说结论,关闭scrapy自带的ROBOTSTXT_OBEY功能,在setting ...
- 007 numpy数组文件的存取
不知道这个有没有用,都整理了一番. 一:数组以二进制格式进行存储 1.说明 np.save与np.load是读写磁盘数组数据的两个重要函数. 默认情况下,数组以压缩的原始二进制格式保存在扩展名为npy ...
- 基于PySpark的网络服务异常检测系统 阶段总结(二)
在上篇博文中介绍了网络服务异常检测的大概,本篇将详细介绍SVDD和Isolation Forest这两种算法 1. SVDD算法 SVDD的英文全称是Support Vector Data Descr ...
- Python 2.7 cython cythonize py 编译成 pyd 谈谈那些坑
Python 2.7 cython cythonize py 编译成 pyd 谈谈那些坑 前言 基于 python27 的 pyc 很容易被反编译,于是想到了pyd,加速运行,安全保护 必要准备 安装 ...
- Java中CardLayout布局方式的应用
import java.awt.CardLayout; import java.awt.Color; import java.awt.Container; import javax.swing.JBu ...
- CentOS 通过yum在线安装MySQL5.7
CentOS 通过yum在线安装MySQL5.7 Step1: 检测系统是否自带安装mysql # yum list installed | grep mysql Step2: 删除系统自带的mysq ...
- windows下编译php7图形库php_ui.dll
CSDN博客 具有图形化编程才有意思,这几天看到了php ui 图形扩展,只是现在只能下载php 7.1的 本次教程编译php7.2.6的 php ui 要是linux下编译起来比较简单 但是 win ...