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过程首先必须分析输入的
(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框架进行处理了。
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.查看运行结果
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)