【Lucene3.6.2入門系列】第11節_高亮

  1. package com.jadyer.lucene;  
  2.   
  3. import java.io.File;  
  4. import java.io.IOException;  
  5.   
  6. import org.apache.lucene.analysis.Analyzer;  
  7. import org.apache.lucene.document.Document;  
  8. import org.apache.lucene.document.Field;  
  9. import org.apache.lucene.index.IndexReader;  
  10. import org.apache.lucene.index.IndexWriter;  
  11. import org.apache.lucene.index.IndexWriterConfig;  
  12. import org.apache.lucene.queryParser.MultiFieldQueryParser;  
  13. import org.apache.lucene.queryParser.QueryParser;  
  14. import org.apache.lucene.search.IndexSearcher;  
  15. import org.apache.lucene.search.Query;  
  16. import org.apache.lucene.search.ScoreDoc;  
  17. import org.apache.lucene.search.TopDocs;  
  18. import org.apache.lucene.search.highlight.Formatter;  
  19. import org.apache.lucene.search.highlight.Fragmenter;  
  20. import org.apache.lucene.search.highlight.Highlighter;  
  21. import org.apache.lucene.search.highlight.QueryScorer;  
  22. import org.apache.lucene.search.highlight.SimpleHTMLFormatter;  
  23. import org.apache.lucene.search.highlight.SimpleSpanFragmenter;  
  24. import org.apache.lucene.store.Directory;  
  25. import org.apache.lucene.store.FSDirectory;  
  26. import org.apache.lucene.util.Version;  
  27. import org.apache.tika.Tika;  
  28.   
  29. import com.chenlb.mmseg4j.analysis.MMSegAnalyzer;  
  30.   
  31. /** 
  32.  * 【Lucene3.6.2入門系列】第11節_高亮 
  33.  * @see 高亮功能屬於Lucene的擴展功能(或者叫做貢獻功能) 
  34.  * @see 其所需jar位於Lucene-3.6.2.zip中的/contrib/highlighter/文件夾中 
  35.  * @see 本例中需要以下4個jar 
  36.  * @see lucene-core-3.6.2.jar 
  37.  * @see lucene-highlighter-3.6.2.jar 
  38.  * @see mmseg4j-all-1.8.5-with-dic.jar 
  39.  * @see tika-app-1.4.jar 
  40.  * @create Aug 7, 2013 11:37:10 AM 
  41.  * @author 玄玉<http://blog.csdn.net/jadyer> 
  42.  */  
  43. public class HelloHighLighter {  
  44.     private Directory directory;  
  45.     private IndexReader reader;  
  46.       
  47.     public HelloHighLighter(){  
  48.         Document doc = null;  
  49.         IndexWriter writer = null;  
  50.         try{  
  51.             directory = FSDirectory.open(new File("myExample/myIndex/"));  
  52.             writer = new IndexWriter(directory, new IndexWriterConfig(Version.LUCENE_36, new MMSegAnalyzer()));  
  53.             writer.deleteAll();  
  54.             for(File myFile : new File("myExample/myFile/").listFiles()){  
  55.                 doc = new Document();  
  56.                 doc.add(new Field("filecontent"new Tika().parse(myFile))); //Field.Store.NO,Field.Index.ANALYZED  
  57.                 doc.add(new Field("filepath", myFile.getAbsolutePath(), Field.Store.YES, Field.Index.NOT_ANALYZED_NO_NORMS));  
  58.                 writer.addDocument(doc);  
  59.             }  
  60.         }catch(Exception e) {  
  61.             e.printStackTrace();  
  62.         }finally{  
  63.             if(null != writer){  
  64.                 try {  
  65.                     writer.close();  
  66.                 } catch (IOException ce) {  
  67.                     ce.printStackTrace();  
  68.                 }  
  69.             }  
  70.         }  
  71.     }  
  72.       
  73.       
  74.     /** 
  75.      * 獲取IndexSearcher實例 
  76.      */  
  77.     private IndexSearcher getIndexSearcher(){  
  78.         try {  
  79.             if(reader == null){  
  80.                 reader = IndexReader.open(directory);  
  81.             }else{  
  82.                 //if the index was changed since the provided reader was opened, open and return a new reader; else,return null  
  83.                 //如果當前reader在打開期間index發生改變,則打開並返回一個新的IndexReader,否則返回null  
  84.                 IndexReader ir = IndexReader.openIfChanged(reader);  
  85.                 if(ir != null){  
  86.                     reader.close(); //關閉原reader  
  87.                     reader = ir;    //賦予新reader  
  88.                 }  
  89.             }  
  90.             return new IndexSearcher(reader);  
  91.         }catch(Exception e) {  
  92.             e.printStackTrace();  
  93.         }  
  94.         return null//發生異常則返回null  
  95.     }  
  96.       
  97.       
  98.     /** 
  99.      * 高亮搜索 
  100.      * @see 高亮搜索時,不建議把高亮信息存到索引裏,而是搜索到內容之後再進行高亮處理 
  101.      * @see 這裏用的是MMSeg4j中文分詞器,有關其介紹詳見http://blog.csdn.net/jadyer/article/details/10049525 
  102.      * @param expr 搜索表達式 
  103.      */  
  104.     public void searchByHignLighter(String expr){  
  105.         Analyzer analyzer = new MMSegAnalyzer();  
  106.         IndexSearcher searcher = this.getIndexSearcher();  
  107.         //搜索多個Field  
  108.         QueryParser parser = new MultiFieldQueryParser(Version.LUCENE_36, new String[]{"filepath""filecontent"}, analyzer);  
  109.         try {  
  110.             Query query = parser.parse(expr);  
  111.             TopDocs tds = searcher.search(query, 50);  
  112.             for(ScoreDoc sd : tds.scoreDocs){  
  113.                 Document doc = searcher.doc(sd.doc);  
  114.                 //獲取文檔內容  
  115.                 String filecontent = new Tika().parseToString(new File(doc.get("filepath")));  
  116.                 System.out.println("搜索到的內容爲[" + filecontent + "]");  
  117.                 //開始高亮處理  
  118.                 QueryScorer queryScorer = new QueryScorer(query);  
  119.                 Fragmenter fragmenter = new SimpleSpanFragmenter(queryScorer, filecontent.length());  
  120.                 Formatter formatter = new SimpleHTMLFormatter("<span style='color:red'>""</span>");  
  121.                 Highlighter hl = new Highlighter(formatter, queryScorer);  
  122.                 hl.setTextFragmenter(fragmenter);  
  123.                 System.out.println("高亮後的內容爲[" + hl.getBestFragment(analyzer, "filecontent", filecontent) + "]");  
  124.             }  
  125.         } catch (Exception e) {  
  126.             e.printStackTrace();  
  127.         } finally {  
  128.             if(null != searcher){  
  129.                 try {  
  130.                     searcher.close(); //記得關閉IndexSearcher  
  131.                 } catch (IOException e) {  
  132.                     e.printStackTrace();  
  133.                 }  
  134.             }  
  135.         }  
  136.     }  
  137.   
  138.       
  139.     /** 
  140.      * 高亮的使用方式 
  141.      * @see 這裏用的是MMSeg4j中文分詞器,有關其介紹詳見http://blog.csdn.net/jadyer/article/details/10049525 
  142.      */  
  143.     private static void testHighLighter(){  
  144.         String fieldName = "myinfo"//這個可以隨便寫,就是起個標識的作用  
  145.         String text = "我來自中國黑龍江省哈爾濱市巴彥縣興隆鎮長春鄉民權村4隊";  
  146.         QueryParser parser = new QueryParser(Version.LUCENE_36, fieldName, new MMSegAnalyzer());  
  147.         try {  
  148.             //MMSeg4j的new MMSegAnalyzer()默認只會對'中國'和'興隆'進行分詞,所以這裏就只高亮它們倆了  
  149.             Query query = parser.parse("中國 興隆");  
  150.             //針對查詢出來的文本,查詢其評分,以便於能夠根據評分決定顯示情況  
  151.             QueryScorer queryScorer = new QueryScorer(query);  
  152.             //對字符串或文本進行分段,SimpleSpanFragmenter構造方法的第二個參數可以指定高亮的文本長度,默認爲100  
  153.             Fragmenter fragmenter = new SimpleSpanFragmenter(queryScorer);  
  154.             //高亮時的高亮格式,默認爲<B></B>,這裏指定爲紅色字體  
  155.             Formatter formatter = new SimpleHTMLFormatter("<span style='color:red'>""</span>");  
  156.             //Highlighter專門用來做高亮顯示  
  157.             //該構造方法還有一個參數爲Encoder,它有兩個實現類DefaultEncoder和SimpleHTMLEncoder  
  158.             //SimpleHTMLEncoder可以忽略掉HTML標籤,而DefaultEncoder則不會忽略HTML標籤  
  159.             Highlighter hl = new Highlighter(formatter, queryScorer);  
  160.             hl.setTextFragmenter(fragmenter);  
  161.             System.out.println(hl.getBestFragment(new MMSegAnalyzer(), fieldName, text));  
  162.         } catch (Exception e) {  
  163.             e.printStackTrace();  
  164.         }  
  165.     }  
  166.       
  167.       
  168.     /** 
  169.      * 小測試一下 
  170.      */  
  171.     public static void main(String[] args) {  
  172.         //測試高亮的基本使用效果  
  173.         HelloHighLighter.testHighLighter();  
  174.         //測試高亮搜索的效果(測試前記得在myExample/myFile/文件夾中準備一個或多個內容包含"依賴"的doc或pdf的等文件)  
  175.         new HelloHighLighter().searchByHignLighter("依賴");  
  176.     }  
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章