MapReduce-倒排索引

环境:
  Hadoop1.x,CentOS6.5,三台虚拟机搭建的模拟分布式环境

  数据:任意数量、格式的文本文件(我用的四个.java代码文件)

方案目标:

  根据提供的文本文件,提取出每个单词在哪个文件中出现了几次,组成倒排索引,格式如下

  Ant FaultyWordCount.java : 1 , WordCount.java : 1

思路:

  因为这个程序需要用到三个变量:单词、文件名、出现的频率,因此需要自定义Writable类,以单词为key,将文件名和出现的频率打包。

  1.先将每行文本的单词进行分割,以K/V=Word/Filename:1的格式分割。

  2.利用Combiner类,将本Map一个文件的先进行一次计数,减少传输量

  3.在Reduce中对Combiner中传输过来的同一个单词的在不同文件出现的频率数据进行组合。

难点:这个程序主要是用到了一个Combiner和自定义了Writable类。在实现的时候,需要注意的是Writable必须默认无参构造函数。

主调用Main类:

package ren.snail;

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.conf.Configured;
import org.apache.hadoop.fs.Path;
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 org.apache.hadoop.util.Tool;
import org.apache.hadoop.util.ToolRunner;

public class Main extends Configured implements Tool {

    public static void main(String[] args) throws Exception {
        // TODO Auto-generated method stub
        int result = ToolRunner.run(new Configuration(), new Main(), args);
        System.exit(result);
    }

    @Override
    public int run(String[] arg0) throws Exception {
        // TODO Auto-generated method stub
        Configuration configuration = getConf();
        Job job = new Job(configuration, "InvertIndex");
        job.setJarByClass(Main.class);
        FileInputFormat.addInputPath(job, new Path(arg0[0]));
        FileOutputFormat.setOutputPath(job, new Path(arg0[1]));

        job.setMapperClass(InvertMapper.class);
        job.setCombinerClass(Combinner.class);  //设置Combiner类
        job.setReducerClass(InvertReducer.class);
        job.setOutputKeyClass(Text.class);
        job.setOutputValueClass(FileFreqWritable.class);
        System.exit(job.waitForCompletion(true) ? 0 : 1);
        return 0;
    }

}

自定义Writbale类

package ren.snail;

import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;

import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.io.Writable;

public class FileFreqWritable implements Writable {
    Text documentID;
    IntWritable fequence;

    public FileFreqWritable()    //必须提供无参构造函数
    {
        this.documentID = new Text();
        this.fequence = new IntWritable();
    }
    public FileFreqWritable(Text id,IntWritable feq) {
        // TODO Auto-generated constructor stub
        this.documentID=id;
        this.fequence =feq;
    }

    public void set(String id,int feq)
    {
        this.documentID.set(id);
        this.fequence.set(feq);
    }

    @Override
    public void readFields(DataInput in) throws IOException {
        // TODO Auto-generated method stub
        documentID.readFields(in);
        fequence.readFields(in);

    }

    @Override
    public void write(DataOutput out) throws IOException {
        // TODO Auto-generated method stub
        documentID.write(out);
        fequence.write(out);
    }

    public Text getDocumentID() {
        return documentID;
    }

    public String toString()
    {
        return documentID.toString()+" : "+fequence.get();
    }
    public IntWritable getFequence() {
        return fequence;
    }

}

Map

package ren.snail;

import java.io.IOException;

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.lib.input.FileSplit;

public class InvertMapper extends Mapper<LongWritable, Text, Text, FileFreqWritable>{
    public void map(LongWritable key,Text value,Context context) throws IOException,InterruptedException
    {
        String data = value.toString().replaceAll("[^a-zA-Z0-9]+", " ");   //将不需要的其他字符都设为空
        String[] values = data.split(" ");
        FileSplit fileSplit = (FileSplit)context.getInputSplit();
        String filename = fileSplit.getPath().getName();
        for (String temp : values) {
            FileFreqWritable obj = new FileFreqWritable(new Text(filename),new IntWritable(1));
            context.write(new Text(temp), obj);
        }

    }
}

Combiner

package ren.snail;

import java.io.IOException;

import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Reducer;

public class Combinner extends Reducer<Text, FileFreqWritable, Text, FileFreqWritable>{
    public void reduce(Text key,Iterable<FileFreqWritable> values,Context context) throws IOException,InterruptedException
    {
        int count = 0 ;
        String id = "";
        for (FileFreqWritable temp : values) {
            count++;
            if(count == 1)
            {
                id=temp.getDocumentID().toString();
            }
        }
        context.write(key,new FileFreqWritable(new Text(id), new IntWritable(count)));
    }
}

Reduce

package ren.snail;

import java.io.IOException;

import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Reducer;

public class InvertReducer extends Reducer<Text, FileFreqWritable, Text, Text> {

    public void reduce(Text key,Iterable<FileFreqWritable> values,Context context) throws IOException,InterruptedException {
        StringBuilder value = new StringBuilder();
        for (FileFreqWritable fileFreqWritable : values) {
            String temp = fileFreqWritable.toString();
            value.append(temp+" , ");
        }
        context.write(key,new Text(value.toString()));
    }
}

其实我的Reduce实现思路可能有点问题,不过大致是这样

时间: 2024-10-24 17:45:37

MapReduce-倒排索引的相关文章

2018-08-03 期 MapReduce倒排索引编程案例1(Combiner方式)

package cn.sjq.bigdata.inverted.index; import java.io.IOException; import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.fs.Path; import org.apache.hadoop.io.LongWritable; import org.apache.hadoop.io.Text; import org.apache.hadoop.map

2018-08-04 期 MapReduce倒排索引编程案例2(jobControll方式)

1.第一阶段MapReduce任务程序 package cn.itcast.bigdata.index; import java.io.IOException; 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 or

MapReduce编程(七) 倒排索引构建

一.倒排索引简介 倒排索引(英语:Inverted index),也常被称为反向索引.置入档案或反向档案,是一种索引方法,被用来存储在全文搜索下某个单词在一个文档或者一组文档中的存储位置的映射.它是文档检索系统中最常用的数据结构. 以英文为例,下面是要被索引的文本: T0="it is what it is" T1="what is it" T2="it is a banana" 我们就能得到下面的反向文件索引: "a": {

MapReduce实现倒排索引

倒排索引 倒排索引"是文档检索系统中最常用的数据结构,被广泛地应用于全文搜索引擎.它主要是用来存储某个单词(或词组)在一个文档或一组文档中的存储位置的映射,即提供了一种根据内容来查找文档的方式.由于不是根据文档来确定文档所包含的内容,而是进行相反的操作,因而称为倒排索引(Inverted Index). file1: MapReduce is simple file2: MapReduce is powerful is simple file3: Hello MapReduce bye MapR

MapReduce实战--倒排索引

本文地址:http://www.cnblogs.com/archimedes/p/mapreduce-inverted-index.html,转载请注明源地址. 1.倒排索引简介 倒排索引(Inverted index),也常被称为反向索引.置入档案或反向档案,是一种索引方法,被用来存储在全文搜索下某个单词在一个文档或者一组文档中的存储位置的映射.它是文档检索系统中最常用的数据结构. 有两种不同的反向索引形式: 一条记录的水平反向索引(或者反向档案索引)包含每个引用单词的文档的列表. 一个单词的

Hadoop实战-MapReduce之倒排索引(八)

倒排索引 (就是key和Value对调的显示结果) 一.需求:下面是用户播放音乐记录,统计歌曲被哪些用户播放过 tom        LittleApple jack       YesterdayOnceMore Rose       MyHeartWillGoOn jack       LittleApple John       MyHeartWillGoOn kissinger  LittleApple kissinger  YesterdayOnceMore 二.最终的效果 Littl

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

不多说,直接上代码. 2016-12-12 21:54:04,509 INFO [org.apache.hadoop.metrics.jvm.JvmMetrics] - Initializing JVM Metrics with processName=JobTracker, sessionId=2016-12-12 21:54:05,166 WARN [org.apache.hadoop.mapreduce.JobSubmitter] - Hadoop command-line option

利用MapReduce实现倒排索引

这里来学习的是利用MapReduce的分布式编程模型来实现简单的倒排索引. 首先什么是倒排索引? 倒排索引是文档检索中最常用的数据结构,被广泛地应用于全文搜索引擎. 它主要是用来存储某个单词(或词组)在一个文档或一组文档中存储位置的映射,即可以通过内容来查找文档: 而不是通过文档来确定文档所包含的内容,因而被称作倒排索引(Inverted Index). 倒排索引的基本原理和建立过程可以用图来说明. 各种类型的文件经过解析后变成纯文本,再经过中文分词,并与对应的文档号进行组合, 就形成了最简单的

倒排索引和MapReduce简介(未完待续)

1.前言 学习hadoop的童鞋,倒排索引这个算法还是挺重要的.这是以后展开工作的基础.首先,我们来认识下什么是倒排索引: 倒排索引简单地就是:根据单词,返回它在哪个文件中出现过,而且频率是多少的结果.这就像百度里的搜索,你输入一个关键字,那么百度引擎就迅速的在它的服务器里找到有该关键字的文件,并根据频率和其他一些策略(如页面点击投票率)等来给你返回结果.这个过程中,倒排索引就起到很关键的作用. 2.MapReduce框架简介 要设计倒排索引这个算法,那么我们首先得知道MapReduce框架中的

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代码分析统计各个单词在两个文本中出现的次数 其实