- package com.jadyer.lucene;
- import java.io.File;
- import java.io.IOException;
- import org.apache.lucene.analysis.Analyzer;
- import org.apache.lucene.document.Document;
- import org.apache.lucene.document.Field;
- import org.apache.lucene.index.IndexReader;
- import org.apache.lucene.index.IndexWriter;
- import org.apache.lucene.index.IndexWriterConfig;
- import org.apache.lucene.queryParser.MultiFieldQueryParser;
- import org.apache.lucene.queryParser.QueryParser;
- import org.apache.lucene.search.IndexSearcher;
- import org.apache.lucene.search.Query;
- import org.apache.lucene.search.ScoreDoc;
- import org.apache.lucene.search.TopDocs;
- import org.apache.lucene.search.highlight.Formatter;
- import org.apache.lucene.search.highlight.Fragmenter;
- import org.apache.lucene.search.highlight.Highlighter;
- import org.apache.lucene.search.highlight.QueryScorer;
- import org.apache.lucene.search.highlight.SimpleHTMLFormatter;
- import org.apache.lucene.search.highlight.SimpleSpanFragmenter;
- import org.apache.lucene.store.Directory;
- import org.apache.lucene.store.FSDirectory;
- import org.apache.lucene.util.Version;
- import org.apache.tika.Tika;
- import com.chenlb.mmseg4j.analysis.MMSegAnalyzer;
- /**
- * 【Lucene3.6.2入門系列】第11節_高亮
- * @see 高亮功能屬於Lucene的擴展功能(或者叫做貢獻功能)
- * @see 其所需jar位於Lucene-3.6.2.zip中的/contrib/highlighter/文件夾中
- * @see 本例中需要以下4個jar
- * @see lucene-core-3.6.2.jar
- * @see lucene-highlighter-3.6.2.jar
- * @see mmseg4j-all-1.8.5-with-dic.jar
- * @see tika-app-1.4.jar
- * @create Aug 7, 2013 11:37:10 AM
- * @author 玄玉<http://blog.csdn.net/jadyer>
- */
- public class HelloHighLighter {
- private Directory directory;
- private IndexReader reader;
- public HelloHighLighter(){
- Document doc = null;
- IndexWriter writer = null;
- try{
- directory = FSDirectory.open(new File("myExample/myIndex/"));
- writer = new IndexWriter(directory, new IndexWriterConfig(Version.LUCENE_36, new MMSegAnalyzer()));
- writer.deleteAll();
- for(File myFile : new File("myExample/myFile/").listFiles()){
- doc = new Document();
- doc.add(new Field("filecontent", new Tika().parse(myFile))); //Field.Store.NO,Field.Index.ANALYZED
- doc.add(new Field("filepath", myFile.getAbsolutePath(), Field.Store.YES, Field.Index.NOT_ANALYZED_NO_NORMS));
- writer.addDocument(doc);
- }
- }catch(Exception e) {
- e.printStackTrace();
- }finally{
- if(null != writer){
- try {
- writer.close();
- } catch (IOException ce) {
- ce.printStackTrace();
- }
- }
- }
- }
- /**
- * 獲取IndexSearcher實例
- */
- private IndexSearcher getIndexSearcher(){
- try {
- if(reader == null){
- reader = IndexReader.open(directory);
- }else{
- //if the index was changed since the provided reader was opened, open and return a new reader; else,return null
- //如果當前reader在打開期間index發生改變,則打開並返回一個新的IndexReader,否則返回null
- IndexReader ir = IndexReader.openIfChanged(reader);
- if(ir != null){
- reader.close(); //關閉原reader
- reader = ir; //賦予新reader
- }
- }
- return new IndexSearcher(reader);
- }catch(Exception e) {
- e.printStackTrace();
- }
- return null; //發生異常則返回null
- }
- /**
- * 高亮搜索
- * @see 高亮搜索時,不建議把高亮信息存到索引裏,而是搜索到內容之後再進行高亮處理
- * @see 這裏用的是MMSeg4j中文分詞器,有關其介紹詳見http://blog.csdn.net/jadyer/article/details/10049525
- * @param expr 搜索表達式
- */
- public void searchByHignLighter(String expr){
- Analyzer analyzer = new MMSegAnalyzer();
- IndexSearcher searcher = this.getIndexSearcher();
- //搜索多個Field
- QueryParser parser = new MultiFieldQueryParser(Version.LUCENE_36, new String[]{"filepath", "filecontent"}, analyzer);
- try {
- Query query = parser.parse(expr);
- TopDocs tds = searcher.search(query, 50);
- for(ScoreDoc sd : tds.scoreDocs){
- Document doc = searcher.doc(sd.doc);
- //獲取文檔內容
- String filecontent = new Tika().parseToString(new File(doc.get("filepath")));
- System.out.println("搜索到的內容爲[" + filecontent + "]");
- //開始高亮處理
- QueryScorer queryScorer = new QueryScorer(query);
- Fragmenter fragmenter = new SimpleSpanFragmenter(queryScorer, filecontent.length());
- Formatter formatter = new SimpleHTMLFormatter("<span style='color:red'>", "</span>");
- Highlighter hl = new Highlighter(formatter, queryScorer);
- hl.setTextFragmenter(fragmenter);
- System.out.println("高亮後的內容爲[" + hl.getBestFragment(analyzer, "filecontent", filecontent) + "]");
- }
- } catch (Exception e) {
- e.printStackTrace();
- } finally {
- if(null != searcher){
- try {
- searcher.close(); //記得關閉IndexSearcher
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
- }
- }
- /**
- * 高亮的使用方式
- * @see 這裏用的是MMSeg4j中文分詞器,有關其介紹詳見http://blog.csdn.net/jadyer/article/details/10049525
- */
- private static void testHighLighter(){
- String fieldName = "myinfo"; //這個可以隨便寫,就是起個標識的作用
- String text = "我來自中國黑龍江省哈爾濱市巴彥縣興隆鎮長春鄉民權村4隊";
- QueryParser parser = new QueryParser(Version.LUCENE_36, fieldName, new MMSegAnalyzer());
- try {
- //MMSeg4j的new MMSegAnalyzer()默認只會對'中國'和'興隆'進行分詞,所以這裏就只高亮它們倆了
- Query query = parser.parse("中國 興隆");
- //針對查詢出來的文本,查詢其評分,以便於能夠根據評分決定顯示情況
- QueryScorer queryScorer = new QueryScorer(query);
- //對字符串或文本進行分段,SimpleSpanFragmenter構造方法的第二個參數可以指定高亮的文本長度,默認爲100
- Fragmenter fragmenter = new SimpleSpanFragmenter(queryScorer);
- //高亮時的高亮格式,默認爲<B></B>,這裏指定爲紅色字體
- Formatter formatter = new SimpleHTMLFormatter("<span style='color:red'>", "</span>");
- //Highlighter專門用來做高亮顯示
- //該構造方法還有一個參數爲Encoder,它有兩個實現類DefaultEncoder和SimpleHTMLEncoder
- //SimpleHTMLEncoder可以忽略掉HTML標籤,而DefaultEncoder則不會忽略HTML標籤
- Highlighter hl = new Highlighter(formatter, queryScorer);
- hl.setTextFragmenter(fragmenter);
- System.out.println(hl.getBestFragment(new MMSegAnalyzer(), fieldName, text));
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
- /**
- * 小測試一下
- */
- public static void main(String[] args) {
- //測試高亮的基本使用效果
- HelloHighLighter.testHighLighter();
- //測試高亮搜索的效果(測試前記得在myExample/myFile/文件夾中準備一個或多個內容包含"依賴"的doc或pdf的等文件)
- new HelloHighLighter().searchByHignLighter("依賴");
- }
- }
【Lucene3.6.2入門系列】第11節_高亮
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.