概述

倒排索引(英语:Inverted index),也常被称为反向索引、置入档案或反向档案,是一种索引方法,被用来存储在全文搜索下某个单词在一个文档或者一组文档中的存储位置的映射。它是文档检索系统中最常用的数据结构。通过倒排索引,可以根据单词快速获取包含这个单词的文档列表。倒排索引主要由两个部分组成:“单词词典”和“倒排文件”。

倒排索引有两种不同的反向索引形式:

  一条记录的水平反向索引(或者反向档案索引)包含每个引用单词的文档的列表。

  一个单词的水平反向索引(或者完全反向索引)又包含每个单词在一个文档中的位置。

  后者的形式提供了更多的兼容性(比如短语搜索),但是需要更多的时间和空间来创建。

现代搜索引擎的索引都是基于倒排索引。相比“签名文件”、“后缀树”等索引结构,“倒排索引”是实现单词到文档映射关系的最佳实现方式和最有效的索引结构。

多Job串联:第一个job产生的输出结果,是第二个job的输入,第二个job执行的前提是获得第一个job的输出结果,第二个job依赖于第一个job,二者是串行执行关系。job1----->job2----->jobn

示例

需求:有大量的文本(文档、网页),需要建立搜索索引。

示例:有a.txt,b.txt,c.txt三个文件,每个文件分别对应一些关键词;

a.txt如下:

map
reduce
MapReduce
index Inverted index
Inverted index
倒排索引
大数据
hadoop MapReduce hdfs
Inverted index

b.txt如下:

hadoop MapReduce hdfs
Inverted index
倒排索引
大数据
map
reduce
MapReduce

c.txt如下:

Inverted index
倒排索引
大数据
hadoop MapReduce hdfs
Inverted index
hadoop MapReduce hdfs
Inverted index
map
reduce
MapReduce

分析如上文件,实现倒排索引并进行多job关联,需要两个job进行解析;

第一个job期望实现如下方式:

Inverted	a.txt-->3
Inverted b.txt-->1
Inverted c.txt-->3
MapReduce a.txt-->2
MapReduce b.txt-->2
MapReduce c.txt-->3
hadoop a.txt-->1
hadoop b.txt-->1
hadoop c.txt-->2
hdfs a.txt-->1
hdfs b.txt-->1
hdfs c.txt-->2
index a.txt-->4
index b.txt-->1
index c.txt-->3
map a.txt-->1
map b.txt-->1
map c.txt-->1
reduce a.txt-->1
reduce b.txt-->1
reduce c.txt-->1
倒排索引 a.txt-->1
倒排索引 b.txt-->1
倒排索引 c.txt-->1
大数据 a.txt-->1
大数据 b.txt-->1
大数据 c.txt-->1

第二个job期望实现最后效果:

Inverted	b.txt-->1	a.txt-->3	c.txt-->3
MapReduce a.txt-->2 b.txt-->2 c.txt-->3
hadoop a.txt-->1 b.txt-->1 c.txt-->2
hdfs a.txt-->1 b.txt-->1 c.txt-->2
index b.txt-->1 c.txt-->3 a.txt-->4
map a.txt-->1 b.txt-->1 c.txt-->1
reduce a.txt-->1 b.txt-->1 c.txt-->1
倒排索引 a.txt-->1 b.txt-->1 c.txt-->1
大数据 a.txt-->1 b.txt-->1 c.txt-->1

代码详情

IndexOne

import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Mapper;
import org.apache.hadoop.mapreduce.Reducer;
import org.apache.hadoop.mapreduce.lib.input.FileSplit; import java.io.IOException; public class IndexOne { } class IndexMapperOne extends Mapper<LongWritable, Text, Text, IntWritable> {
String name;
Text tKey = new Text();
IntWritable tValue = new IntWritable(); @Override
protected void setup(Context context) throws IOException, InterruptedException {
//获取文件对象
FileSplit inputSplit = (FileSplit) context.getInputSplit();
//获取文件名
name = inputSplit.getPath().getName();
} @Override
protected void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException {
//获取数据
String line = value.toString();
//切分关键词
String[] words = line.split(" ");
for (String word : words) {
//将关键词和文件名字拼接,作为输出的key
tKey.set(word + "@" + name);
tValue.set(1);
context.write(tKey, tValue);
}
}
} class IndexReduceOne extends Reducer<Text, IntWritable, Text, Text> { @Override
protected void reduce(Text key, Iterable<IntWritable> values, Context context) throws IOException, InterruptedException {
String line = key.toString();
String[] splits = line.split("@");
StringBuilder builder = new StringBuilder();
int count = 0;
for (IntWritable number : values) {
count += number.get();
}
builder.append(splits[1] + "-->" + count);
context.write(new Text(splits[0]), new Text(builder.toString()));
}
}

IndexTwo

package descIndex;

import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Mapper;
import org.apache.hadoop.mapreduce.Reducer; import java.io.IOException; public class IndexTwo { } class IndexMapperTwo extends Mapper<LongWritable, Text, Text, Text> { @Override
protected void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException {
String line = value.toString();
String[] splits = line.split("\t");
context.write(new Text(splits[0]), new Text(splits[1]));
}
} class IndexReduceTwo extends Reducer<Text, Text, Text, Text> { @Override
protected void reduce(Text key, Iterable<Text> values, Context context) throws IOException, InterruptedException {
StringBuilder builder = new StringBuilder();
for (Text txt : values) {
builder.append(txt + "\t");
}
context.write(key, new Text(builder.toString()));
}
}

JobUtils

package descIndex;

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Job;
import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat; import java.io.File;
import java.io.IOException; public class JobUtils { private static Configuration conf; static {
conf = new Configuration();
} /**
* 获得job实例
* @param paths 输入与输出路径数组
* @param params 类的可变数组
* @return job实例
* @throws IOException
*/
public static Job getJobInstance(String[] paths, Class... params) throws IOException { Job job = Job.getInstance(conf);
job.setJarByClass(params[0]);
job.setMapperClass(params[1]);
job.setReducerClass(params[2]); job.setMapOutputKeyClass(params[3]);
job.setMapOutputValueClass(params[4]);
job.setOutputKeyClass(params[5]);
job.setOutputValueClass(params[6]); FileInputFormat.setInputPaths(job, new Path(paths[0]));
FileOutputFormat.setOutputPath(job, new Path(paths[1]));
return job;
} }

IndexDriver

package descIndex;

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Job;
import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
import org.apache.hadoop.mapreduce.lib.jobcontrol.ControlledJob;
import org.apache.hadoop.mapreduce.lib.jobcontrol.JobControl;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat; import java.io.IOException; public class IndexDriver {
public static void main(String[] args) throws IOException, InterruptedException { String[] paths1 = {"F:/index", "F:/outindex1"};
Job job1 = JobUtils.getJobInstance(paths1,IndexDriver.class,IndexMapperOne.class,IndexReduceOne.class
,Text.class,IntWritable.class,Text.class,Text.class); String[] paths2 = {"F:/outindex1", "F:/outindex2"};
Job job2 = JobUtils.getJobInstance(paths2,IndexDriver.class,IndexMapperTwo.class,IndexReduceTwo.class
,Text.class,Text.class,Text.class,Text.class); ControlledJob cjJob1 = new ControlledJob(job1.getConfiguration());
ControlledJob cjJob2 = new ControlledJob(job2.getConfiguration());
//创建管理job任务的control组
JobControl ssrs = new JobControl("ssrs");
//添加job
ssrs.addJob(cjJob1);
ssrs.addJob(cjJob2);
//添加任务依赖关系
cjJob2.addDependingJob(cjJob1);
//线程提交
Thread t1 = new Thread(ssrs);
t1.start(); while(!ssrs.allFinished()){
Thread.sleep(1000);
} System.exit(0);
}
}

【Hadoop】MapReduce练习:多job关联实现倒排索引的更多相关文章

  1. Hadoop MapReduce编程 API入门系列之倒排索引(二十四)

    不多说,直接上代码. 2016-12-12 21:54:04,509 INFO [org.apache.hadoop.metrics.jvm.JvmMetrics] - Initializing JV ...

  2. Hadoop MapReduce编程学习

    一直在搞spark,也没时间弄hadoop,不过Hadoop基本的编程我觉得我还是要会吧,看到一篇不错的文章,不过应该应用于hadoop2.0以前,因为代码中有  conf.set("map ...

  3. Hadoop MapReduce编程入门案例

    Hadoop入门例程简介 一个.有些指令 (1)Hadoop新与旧API差异 新API倾向于使用虚拟课堂(象类),而不是接口.由于这更easy扩展. 比如,能够无需改动类的实现而在虚类中加入一个方法( ...

  4. Hadoop MapReduce 保姆级吐血宝典,学习与面试必读此文!

    Hadoop 涉及的知识点如下图所示,本文将逐一讲解: 本文档参考了关于 Hadoop 的官网及其他众多资料整理而成,为了整洁的排版及舒适的阅读,对于模糊不清晰的图片及黑白图片进行重新绘制成了高清彩图 ...

  5. 使用Python实现Hadoop MapReduce程序

    转自:使用Python实现Hadoop MapReduce程序 英文原文:Writing an Hadoop MapReduce Program in Python 根据上面两篇文章,下面是我在自己的 ...

  6. MapReduce业务 - 图片关联计算

    1.概述 最近在和人交流时谈到数据相似度和数据共性问题,而刚好在业务层面有类似的需求,今天和大家分享这类问题的解决思路,分享目录如下所示: 业务背景 编码实践 预览截图 下面开始今天的内容分享. 2. ...

  7. Hadoop Mapreduce 案例 wordcount+统计手机流量使用情况

    mapreduce设计思想 概念:它是一个分布式并行计算的应用框架它提供相应简单的api模型,我们只需按照这些模型规则编写程序,即可实现"分布式并行计算"的功能. 案例一:word ...

  8. Hadoop学习笔记(8) ——实战 做个倒排索引

    Hadoop学习笔记(8) ——实战 做个倒排索引 倒排索引是文档检索系统中最常用数据结构.根据单词反过来查在文档中出现的频率,而不是根据文档来,所以称倒排索引(Inverted Index).结构如 ...

  9. Hadoop MapReduce编程 API入门系列之计数器(二十七)

    不多说,直接上代码. MapReduce 计数器是什么?    计数器是用来记录job的执行进度和状态的.它的作用可以理解为日志.我们可以在程序的某个位置插入计数器,记录数据或者进度的变化情况. Ma ...

随机推荐

  1. OI界的事

    随时更新: 目前在中大型考试上已经因为freopen相关的锅导致此题爆零共有: 5次.并且因此参加不了提高组(菜到无人反驳) 本人:学oi半年的练习生)蒟蒻 ,擅长水红题,橙题,博客,以及电子方面. ...

  2. SQL server 自定义函数FUNCTION的使用

    原文链接:https://blog.csdn.net/lanxingbudui/article/details/81736402 前言:        在SQL server中不仅可以可以使用系统自带 ...

  3. selenium+pyquery爬取淘宝商品信息

    import re from selenium import webdriver from selenium.common.exceptions import TimeoutException fro ...

  4. 智能指针weak_ptr记录

    智能指针weak_ptr为弱共享指针,实际上是share_ptr的辅助指针,不具备指针的功能.主要是为了协助 shared_ptr 工作,可用来观测资源的使用情况.weak_ptr 只对 shared ...

  5. 模板方法(Template Method)---行为型

    1 基础知识 定义:定义了一个算法的骨架并允许子类为一个或多个步骤提供实现.特征:模板方法使得子类可以在不改变算法结构的前提下重新定义某些步骤. 使用场景: (1)需要固定定义算法骨架,实现一个算法的 ...

  6. 根据xml文件生成javaBean

    原 根据xml文件生成javaBean 2017年08月15日 18:32:26 吃完喝完嚼益达 阅读数 1727 版权声明:本文为博主原创文章,遵循CC 4.0 by-sa版权协议,转载请附上原文出 ...

  7. openstack导入镜像

    本文以制作CentOS7.2镜像为例,详细介绍手动制作OpenStack镜像详细步骤,解释每一步这么做的原因.镜像上传到OpenStack glance,支持以下几个功能: 支持密码注入功能(nova ...

  8. 发布mybatis-generator-core 1.3.5的中文注释版

    源码剖析介绍:基于mybatis-generator-core 1.3.5项目的修订版以及源码剖析 目前,我把该项目,发布到了Maven中央仓库中,可直接使用: 使用方式 在项目.pom中,添加以下部 ...

  9. jquery+ajax 实现搜索框提示

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  10. Python中调用shell

    1 简单调用shell命令 os.system(command) 在一个子shell中运行command命令, 并返回command命令执行完毕后的退出状态. 这实际上是使用C标准库函数system( ...