大數據學習之十三——倒排索引

倒排索引java

1.瞭解概念算法

"倒排索引"是文檔檢索系統中最經常使用的數據結構,被普遍地應用於全文搜索引擎。它主要是用來存儲某個單詞(或詞組)在一個文檔或一組文檔中的存儲位置的映射,即提供了一種根據內容來查找文檔的方式。因爲不是根據文檔來肯定文檔所包含的內容,而是進行相反的操做,於是稱爲倒排索引(Inverted Index)。數組

2.實例描述
一般狀況下,倒排索引由一個單詞(或詞組)以及相關的文檔列表組成,文檔列表中的文檔或者是標識文檔的ID號,或者是指文檔所在位置的URL。在實際應用中,還須要給每一個文檔添加一個權值,用來指出每一個文檔與搜索內容的相關度數據結構

3.樣例輸入輸出app

4.算法思想框架

1)map過程搜索引擎

爲統計每一個單詞出如今每一個文件中的次數,將單詞word做爲map階段的key值,「filename:1」做爲value值。能夠獲得上圖的結果。傳到combine的格式爲:MapReduce:file1.txt3d

這樣作的好處是:能夠利用MapReduce框架自帶的Map端排序,將同一文檔的相同單詞的詞頻組成列表,傳遞給Combine過程,實現相似於WordCount的功能。orm

2)combine階段blog

通過map方法處理後,Combine過程將key值相同的value值累加,獲得一個單詞在每一個文檔中出現的次數,若是直接將圖所示的輸出做爲Reduce過程的輸入,在Shuffle過程時將面臨一個問題:全部具備相同單詞的記錄(由word、filename和次數組成)應該交由同一個Reducer處理,但當前的key值沒法保證這一點,因此必須修改key值和value值。此次將單詞做爲key值,filename和詞頻組成value值(如"file1.txt:1")。

3)reduce過程

reduce過程只需將相同key值的value值組合成倒排索引文件所需的格式便可,剩下的事情就能夠直接交給MapReduce框架進行處理了。

5.代碼實現

public class InvertedIndex {     

static String INPUT_PATH="hdfs://master:9000/index";  

static String OUTPUT_PATH="hdfs://master:9000/output/index";    

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

private Text output_key=new Text();   

private Text output_value=new Text();  

 String fileName=new String();      

protected void setup(Context context)throws java.io.IOException,java.lang.InterruptedException{   

 FileSplit fs=(FileSplit)context.getInputSplit();     //獲得文件的名字filename

fileName=fs.getPath().getName();    

System.out.println(fileName);    

 }      

protected void map(Object key, Object value, Context context) throws IOException, InterruptedException{    

String[] tokens=value.toString().split(" ");      //以空格爲分隔

if(tokens!=null){    

 for(int i=0;i<tokens.length;i++){     

 output_key.set(tokens[i]+":"+fileName);     //設置 key---word:filename      

output_value.set("1");                 //每出現一次+1       

context.write(output_key, output_value);      

System.out.print("1=="+output_key);      

System.out.println("1=="+output_value);     //1==simple:a02.txt         1== 1    

 }        

 }  

 }

 }  

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

 Text output_key=new Text();   

Text output_value=new Text();      

protected void reduce(Text key,Iterable<Text> values,Context context) throws IOException,InterruptedException{    

String[] tokens=key.toString().split(":");      //將word和filename以:分隔開

int sum=0;    

for(Text val:values){    

 sum+=Integer.parseInt(val.toString());    //將單詞相同的1相加

 }        

 output_key.set(tokens[0]);    

output_value.set(tokens[1]+":"+sum);   

 context.write(output_key, output_value);  //2==mapreduce  2==a01.txt:1    

System.out.print("2=="+output_key);    

System.out.println("2=="+output_value);  

 }

 }  

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

private Text result = new Text();   

protected void reduce(Text key,Iterable<Text> values,Context context) throws IOException,InterruptedException{   

 String fileList = new String();    

for (Text value : values){         //鏈接filename和出現的次數

fileList += value.toString() + ";" ;   

 }    

result.set(fileList);    

context.write(key,result);   

 System.out.println("3=="+key);  

 }

 }    

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

Path outputpath=new Path(OUTPUT_PATH);   

Configuration conf=new Configuration();       

FileSystem file = outputpath.getFileSystem(conf);  

 if(file.exists(outputpath)){   

 file.delete(outputpath,true);   

}      

Job job=Job.getInstance(conf);   

FileInputFormat.setInputPaths(job, INPUT_PATH);   

FileOutputFormat.setOutputPath(job,outputpath);      

job.setMapperClass(MyMapper.class);   

job.setReducerClass(MyReduce.class);  

 job.setCombinerClass(Mycombine.class);      

job.setOutputKeyClass(Text.class);  

 job.setOutputValueClass(Text.class);     

 job.waitForCompletion(true);

 }

}

相關文章
相關標籤/搜索