Hadoop3.2.2实现倒排索引

Hadoop3.2.2实现倒排索引,第1张

本文是使用MapReduce并行分布式计算框架进行编程,实现倒排索引建立;

1.倒排索引的介绍
“倒排索引”是文档检索系统中最常用的数据结构,被广泛地应用于全文搜索引擎。它主要是用来存储某个单词(或词组)在一个文档或一组文档中的存储位置的映射,即提供了一种根据内容来查找文档的方式。由于不是根据文档来确定文档所包含的内容,而是进行相反的 *** 作,因而称为倒排索引(Inverted Index)。
2.样例输入如下

1)file1

MapReduce is simple

2)file2

MapReduce is powerful is simple

3)file3

Hello MapReduce bye MapReduce

3、样例输出如下

MapReduce file1.txt:1;file2.txt:1;file3.txt:2;

is     file1.txt:1;file2.txt:2;

simple   file1.txt:1;file2.txt:1;

powerful    file2.txt:1;

Hello    file3.txt:1;

bye    file3.txt:1;
4.设计思路
(1)首先使用默认的TextInputFormat类对输入文件进行处理,得到文本中每行的偏移量及其内容。显然,Map过程首先必须分析输入的对,得到倒排索引中需要的三个信息:单词、文档名和词频。将单词和URL组成key值(如"MapReduce:file1.txt"),将词频作为value,这样做的好处是可以利用MapReduce框架自带的Map端排序。
(2)Combine过程:经过map方法处理后,Combine过程将key值相同的value值累加,得到一个单词在文档中的词频,如图5所示。如果直接将图所示的输出作为Reduce过程的输入,在Shuffle过程时将面临一个问题:所有具有相同单词的记录(由单词、URL和词频组成)应该交由同一个Reducer处理,但当前的key值无法保证这一点,所以必须修改key值和value值。这次将单词作为key值,URL和词频组成value值(如"file1.txt:1")。这样做的好处是可以利用MapReduce框架默认的HashPartitioner类完成Shuffle过程,将相同单词的所有记录发送给同一个Reducer进行处理。
(3)Reduce过程:经过上述两个过程后,Reduce过程只需将相同key值的value值组合成倒排索引文件所需的格式即可,剩下的事情就可以直接交给MapReduce框架进行处理了。

#########开始处理############# 1.在eclipse中编写java程序,导出jar包到/home/baga29/hadoop/goodjars 目录下,并命名为IndexInverse.jar

java程序内容如下,库的导入参考这一篇文章中的导入:

https://blog.csdn.net/weixin_45861496/article/details/124503944

import java.io.IOException;

import java.util.StringTokenizer;

import org.apache.hadoop.conf.Configuration;

import org.apache.hadoop.fs.FileSystem;

import org.apache.hadoop.fs.Path;

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;

public class IndexInverse {

     static class IIMap extends Mapper<Object,Text,Text,Text>{

          private Text mkey=new Text();//保存map的输出key,单词,URL

          private FileSplit split;

          @Override

          protected void map(Object key, Text value, Mapper<Object, Text, Text, Text>.Context context)

                   throws IOException, InterruptedException {

              split=(FileSplit) context.getInputSplit();

              StringTokenizer st=new StringTokenizer(value.toString());

              while(st.hasMoreTokens()){

                   String word=st.nextToken();

                   //String url=split.getPath().toString();

                   //mkey.set(word+" "+url);

                   int url=split.getPath().toString().indexOf("file");

                   mkey.set(word+" "+split.getPath().toString().substring(url));

                   

                   context.write(mkey, new Text("1"));

              }

          }

          

     }

     static class Combinator extends Reducer<Text,Text,Text,Text>{

          private Text mkey=new Text();

          private Text mvalue=new Text();

          @Override

          protected void reduce(Text arg0, Iterable<Text> arg1,

                   Reducer<Text, Text, Text, Text>.Context arg2) throws IOException, InterruptedException {

              int sum=0;

              for(Text i:arg1){

                   sum+=Integer.valueOf(i.toString());

              }

              String[] sk=arg0.toString().split(" ");

              mkey.set(sk[0]);

              mvalue.set(sk[1]+"["+sum+"]");

              arg2.write(mkey, mvalue);

          }

          

          

     }

     static class IIReduce extends Reducer<Text,Text,Text,Text>{

          private Text mvalue=new Text();

          

              @Override

          protected void reduce(Text arg0, Iterable<Text> arg1,

                   Reducer<Text, Text, Text, Text>.Context arg2) throws IOException, InterruptedException {

              

              String s=" ";

              for(Text t:arg1){

                   s+="--"+t.toString();

              }

              mvalue.set(s);

              arg2.write(arg0, mvalue);

          }

     }

     public static void main(String[] args) throws Exception{

          if(args.length!=2){

              System.err.println("wrong");

              System.exit(2);

          }

          Configuration conf=new Configuration();

          FileSystem hdfs=FileSystem.get(conf);

          hdfs.delete(new Path(args[1]),true); //如果目录已经存在,先删除,如果目录不存在,这行不需要写

          

          Job job=Job.getInstance(conf);

          job.setJarByClass(IndexInverse.class);

          job.setJobName("Inverted Index");

          

          job.setMapperClass(IIMap.class);

          job.setCombinerClass(Combinator.class);

          job.setReducerClass(IIReduce.class);

          

          //job.setMapOutputKeyClass(Text.class);

          job.setMapOutputValueClass(Text.class);

          

          job.setOutputKeyClass(Text.class);

          job.setOutputValueClass(Text.class);

          

          FileInputFormat.addInputPath(job, new Path(args[0]));

          FileOutputFormat.setOutputPath(job, new Path(args[1]));    

          System.exit(job.waitForCompletion(true)?0:1);

     }

}

2.创建示例文件内容并且上传到hdfs文件系统中。

3.在hadoop102上运行

4.查看运行结果

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/906296.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-15
下一篇 2022-05-15

发表评论

登录后才能评论

评论列表(0条)

保存