`
jetway
  • 浏览: 473436 次
  • 性别: Icon_minigender_1
  • 来自: 武汉
社区版块
存档分类
最新评论

HighLighter

    博客分类:
  • java
阅读更多

今天搞了一个关于Lucene的例子,权当入门教程。网上有很多资料,但是要么不全、要么不好用,所以这里把全部代码以及依赖的包贴上来了。



功能包括:创建索引、检索索引、高亮显示查询结果。分词使用的庖丁解牛。



使用前先下载相关的LuceneCore jar包、LuceneHighLighter jar包、庖丁解牛分分词jar包、庖丁解牛词典。并设定环境变量PAODING_DIC_HOME指向词典位置。

前两个可以到官方网站找,庖丁去http://code.google.com/p/paoding/downloads/list下载。



Lucene庖丁整合方式1:

1、将paoding-analysis.jar拷贝到项目的WEB-INF/lib目录;
2、接着需要设置环境变量PAODING_DIC_HOME,变量名:PAODING_DIC_HOME 变量值:E:\paoding\dic
3、第三步将E:\paoding\src目录下的paoding-dic-home.properties属性文件拷贝到项目的src目录下,添加2行

paoding.dic.home.config-fisrt=this
paoding.dic.home=E:/paoding/dic

Lucene庖丁整合方式2:

修改E:\paoding\src\paoding-dic-home.properties,增加一行

paoding.dic.home=classpath:dic

然后运行ant重新生成一个庖丁jar,拷贝到lib下就OK了。

第一种方式便于更新字典,第二种便于移植。本例使用第二种方法整合。

关于庖丁环境的设置可以参考net\paoding\analysis\Constants.java。





使用时注意LuceneCore和LuceneHighLighter的版本配置。我开始使用lucene-core-2.3.2.jar+Highlighter 2.4,后台报错,明显的版本问题。现在使用的是Lucene 2.3.2 + Highlighter 2.2.0。



主要代码实现:

CreateIndex:创建索引文件

Java代码 复制代码
  1. package demo;      
  2.      
  3. import java.io.BufferedReader;      
  4. import java.io.File;      
  5. import java.io.FileInputStream;      
  6. import java.io.IOException;      
  7. import java.io.InputStreamReader;      
  8. import java.util.Date;      
  9.      
  10. import net.paoding.analysis.analyzer.PaodingAnalyzer;      
  11.      
  12. import org.apache.lucene.analysis.Analyzer;      
  13. import org.apache.lucene.document.Document;      
  14. import org.apache.lucene.document.Field;      
  15. import org.apache.lucene.index.IndexWriter;      
  16.      
  17.      
  18. /**    
  19.  * 建立索引    
  20.  *     
  21.  */     
  22. public class CreateIndex {      
  23.           
  24.     public void createIndex() throws Exception {      
  25.         /* 指明要索引文件夹的位置,这里是C盘的S文件夹下 */     
  26.         File surceFileDir = new File("D:\\save\\source");      
  27.      
  28.         /* 这里放索引文件的位置 */     
  29.         File indexFileDir = new File("D:\\save");      
  30.               
  31.         //Analyzer luceneAnalyzer = new StandardAnalyzer();      
  32.         Analyzer luceneAnalyzer = new PaodingAnalyzer();//使用庖丁解牛分词法      
  33.               
  34.         IndexWriter indexWriter = new IndexWriter(indexFileDir, luceneAnalyzer, true);///参数isEmpty是false表示增量索引      
  35.         File[] sourceFextFiles = surceFileDir.listFiles();      
  36.         long startTime = new Date().getTime();      
  37.      
  38.         // 增加document到索引去      
  39.         for (int i = 0; i < sourceFextFiles.length; i++) {      
  40.             if (sourceFextFiles[i].isFile()      
  41.                     && sourceFextFiles[i].getName().endsWith(".txt")) {      
  42.                 System.out.println("File " + sourceFextFiles[i].getCanonicalPath() + "正在被索引....");      
  43.                 String temp = FileReaderAll(sourceFextFiles[i].getCanonicalPath(), "GBK");      
  44.                 System.out.println(temp);      
  45.                 Document document = new Document();      
  46.                 Field FieldPath = new Field("path", sourceFextFiles[i].getPath(), Field.Store.YES, Field.Index.NO);      
  47.                 Field FieldBody = new Field("body", temp, Field.Store.YES, Field.Index.TOKENIZED, Field.TermVector.WITH_POSITIONS_OFFSETS);      
  48.                 Field FieldTitle = new Field("title", temp, Field.Store.YES, Field.Index.TOKENIZED, Field.TermVector.WITH_POSITIONS_OFFSETS);      
  49.                 document.add(FieldPath);      
  50.                 document.add(FieldBody);document.add(FieldTitle);      
  51.                 indexWriter.addDocument(document);      
  52.             }      
  53.         }      
  54.         // optimize()方法是对索引进行优化      
  55.         indexWriter.optimize();      
  56.         indexWriter.close();      
  57.      
  58.         // 测试一下索引的时间      
  59.         long endTime = new Date().getTime();      
  60.         System.out.println("这花费了" + (endTime - startTime) + " 毫秒来把文档增加到索引里面去!"     
  61.                 + indexFileDir.getPath());      
  62.     }      
  63.      
  64.     public static String FileReaderAll(String FileName, String charset)      
  65.             throws IOException {      
  66.         BufferedReader reader = new BufferedReader(new InputStreamReader(      
  67.                 new FileInputStream(FileName), charset));      
  68.         String line = new String();      
  69.         String temp = new String();      
  70.      
  71.         while ((line = reader.readLine()) != null) {      
  72.             temp += line;      
  73.         }      
  74.         reader.close();      
  75.         return temp;      
  76.     }      
  77.      
  78.     /**    
  79.      * @param args    
  80.      */     
  81.     public static void main(String[] args) {      
  82.         try {      
  83.             new CreateIndex().createIndex();      
  84.         } catch (Exception e) {      
  85.             e.printStackTrace();      
  86.         }      
  87.      
  88.     }      
  89.      
  90. }    
package demo;   
  
import java.io.BufferedReader;   
import java.io.File;   
import java.io.FileInputStream;   
import java.io.IOException;   
import java.io.InputStreamReader;   
import java.util.Date;   
  
import net.paoding.analysis.analyzer.PaodingAnalyzer;   
  
import org.apache.lucene.analysis.Analyzer;   
import org.apache.lucene.document.Document;   
import org.apache.lucene.document.Field;   
import org.apache.lucene.index.IndexWriter;   
  
  
/**  
 * 建立索引  
 *   
 */  
public class CreateIndex {   
       
    public void createIndex() throws Exception {   
        /* 指明要索引文件夹的位置,这里是C盘的S文件夹下 */  
        File surceFileDir = new File("D:\\save\\source");   
  
        /* 这里放索引文件的位置 */  
        File indexFileDir = new File("D:\\save");   
           
        //Analyzer luceneAnalyzer = new StandardAnalyzer();   
        Analyzer luceneAnalyzer = new PaodingAnalyzer();//使用庖丁解牛分词法   
           
        IndexWriter indexWriter = new IndexWriter(indexFileDir, luceneAnalyzer, true);///参数isEmpty是false表示增量索引   
        File[] sourceFextFiles = surceFileDir.listFiles();   
        long startTime = new Date().getTime();   
  
        // 增加document到索引去   
        for (int i = 0; i < sourceFextFiles.length; i++) {   
            if (sourceFextFiles[i].isFile()   
                    && sourceFextFiles[i].getName().endsWith(".txt")) {   
                System.out.println("File " + sourceFextFiles[i].getCanonicalPath() + "正在被索引....");   
                String temp = FileReaderAll(sourceFextFiles[i].getCanonicalPath(), "GBK");   
                System.out.println(temp);   
                Document document = new Document();   
                Field FieldPath = new Field("path", sourceFextFiles[i].getPath(), Field.Store.YES, Field.Index.NO);   
                Field FieldBody = new Field("body", temp, Field.Store.YES, Field.Index.TOKENIZED, Field.TermVector.WITH_POSITIONS_OFFSETS);   
                Field FieldTitle = new Field("title", temp, Field.Store.YES, Field.Index.TOKENIZED, Field.TermVector.WITH_POSITIONS_OFFSETS);   
                document.add(FieldPath);   
                document.add(FieldBody);document.add(FieldTitle);   
                indexWriter.addDocument(document);   
            }   
        }   
        // optimize()方法是对索引进行优化   
        indexWriter.optimize();   
        indexWriter.close();   
  
        // 测试一下索引的时间   
        long endTime = new Date().getTime();   
        System.out.println("这花费了" + (endTime - startTime) + " 毫秒来把文档增加到索引里面去!"  
                + indexFileDir.getPath());   
    }   
  
    public static String FileReaderAll(String FileName, String charset)   
            throws IOException {   
        BufferedReader reader = new BufferedReader(new InputStreamReader(   
                new FileInputStream(FileName), charset));   
        String line = new String();   
        String temp = new String();   
  
        while ((line = reader.readLine()) != null) {   
            temp += line;   
        }   
        reader.close();   
        return temp;   
    }   
  
    /**  
     * @param args  
     */  
    public static void main(String[] args) {   
        try {   
            new CreateIndex().createIndex();   
        } catch (Exception e) {   
            e.printStackTrace();   
        }   
  
    }   
  
}  


QueryHighLighter:检索关键字并高亮显示

Java代码 复制代码
  1. package demo;      
  2.      
  3. import java.io.StringReader;      
  4.      
  5. import net.paoding.analysis.analyzer.PaodingAnalyzer;      
  6.      
  7. import org.apache.lucene.analysis.Analyzer;      
  8. import org.apache.lucene.analysis.TokenStream;      
  9. import org.apache.lucene.document.Document;      
  10. import org.apache.lucene.queryParser.QueryParser;      
  11. import org.apache.lucene.search.BooleanClause;      
  12. import org.apache.lucene.search.IndexSearcher;      
  13. import org.apache.lucene.search.Query;      
  14. import org.apache.lucene.search.ScoreDoc;      
  15. import org.apache.lucene.search.TopDocCollector;      
  16. import org.apache.lucene.search.highlight.Highlighter;      
  17. import org.apache.lucene.search.highlight.QueryScorer;      
  18. import org.apache.lucene.search.highlight.SimpleFragmenter;      
  19. import org.apache.lucene.search.highlight.SimpleHTMLFormatter;      
  20.      
  21. import test.TestLuceneHighlighter2;      
  22.      
  23.      
  24. /**    
  25.  * 高亮显示检索结果    
  26.  * Lucene 2.3.2 + Highlighter 2.2.0 的分页+高亮显示代码例子.<br>    
  27.  * Lucene和Highlighter不是最新版本可以升级。    
  28.  */     
  29. public class QueryHighLighter {      
  30.      
  31.     private static final String FIELD_TITLE = "title";      
  32.      
  33.     private static final String FIELD_BODY = "body";      
  34.      
  35.     public synchronized Analyzer getAnalyzer() {      
  36.         return new PaodingAnalyzer();// 此处使用"庖丁解牛"分词法,另外一种是中科院分词法      
  37.     }      
  38.      
  39.     public String test(String queryString, int begin, int number) {      
  40.         StringBuffer sb = new StringBuffer();      
  41.         IndexSearcher isearcher = null;      
  42.         try {      
  43.             isearcher = new IndexSearcher("D:\\save");      
  44.             /* 下面这个表示要同时搜索这两个域,而且只要一个域里面有满足我们搜索的内容就行 */     
  45.             BooleanClause.Occur[] clauses = { BooleanClause.Occur.SHOULD,      
  46.                     BooleanClause.Occur.SHOULD };      
  47.             TopDocCollector collector = new TopDocCollector(10);      
  48.             /*Query query = MultiFieldQueryParser.parse(queryString,    
  49.                     new String[] { FIELD_TITLE, FIELD_BODY }, clauses,    
  50.                     getAnalyzer());*/     
  51.             QueryParser queryParse = new QueryParser(FIELD_TITLE, getAnalyzer());         
  52.             Query query = queryParse.parse(queryString);        
  53.                   
  54.             isearcher.search(query, collector);      
  55.             ScoreDoc[] hits = collector.topDocs().scoreDocs;      
  56.             // 用这个进行高亮显示,默认是<b>..</b>      
  57.             // 用这个指定<read>..</read>      
  58.             SimpleHTMLFormatter simpleHTMLFormatter = new SimpleHTMLFormatter("<b><font color='red'>""</font></b>");      
  59.             // 构造高亮      
  60.             // 指定高亮的格式      
  61.             // 指定查询评分      
  62.             Highlighter highlighter = new Highlighter(simpleHTMLFormatter, new QueryScorer(query));      
  63.             // 这个一般等于你要返回的,高亮的数据长度      
  64.             // 如果太小,则只有数据的开始部分被解析并高亮,且返回的数据也少      
  65.             // 太大,有时太浪费了。      
  66.             highlighter.setTextFragmenter(new SimpleFragmenter(Integer.MAX_VALUE));      
  67.             for (int i = begin; i < hits.length && i < begin + number; i++) {      
  68.                 Document doc = isearcher.doc(hits[i].doc);      
  69.                 String value = doc.get(FIELD_TITLE);      
  70.                 String value2 = doc.get(FIELD_BODY);      
  71.                 // 有三个参数      
  72.                 // 分析器      
  73.                 // 要解析的字段名      
  74.                 // 要解析的数据      
  75.                 //System.out.println(highlighter.getBestFragment(getAnalyzer(),      
  76.                 //      FIELD_TITLE, doc.get(FIELD_TITLE)));      
  77.                       
  78.                 if (value != null) {      
  79.                     TokenStream tokenStream = getAnalyzer().tokenStream(FIELD_TITLE, new StringReader(value));      
  80.                     String str = highlighter.getBestFragment(tokenStream, value);      
  81.                     sb.append("<li><li>").append(str).append("<br/>");      
  82.                     System.out.println(str);      
  83.                 }       
  84.                       
  85.             }      
  86.         } catch (Exception e) {      
  87.             e.printStackTrace();      
  88.         } finally {      
  89.             if (isearcher != null) {      
  90.                 try {      
  91.                     isearcher.close();      
  92.                 } catch (Exception e) {      
  93.                     e.printStackTrace();      
  94.                 }      
  95.             }      
  96.         }      
  97.         return sb.toString();      
  98.     }      
  99.           
  100.     public static void main(String[] args){      
  101.         TestLuceneHighlighter2 t = new TestLuceneHighlighter2();      
  102.         String queryString = "中华人民共和国";      
  103.         int begin = 0;      
  104.         int number = 10;      
  105.         t.test(queryString, begin, number);      
  106.     }      
  107.      
  108. }     
  109.   
  110. package demo;   
  111.   
  112. import java.io.StringReader;   
  113.   
  114. import net.paoding.analysis.analyzer.PaodingAnalyzer;   
  115.   
  116. import org.apache.lucene.analysis.Analyzer;   
  117. import org.apache.lucene.analysis.TokenStream;   
  118. import org.apache.lucene.document.Document;   
  119. import org.apache.lucene.queryParser.QueryParser;   
  120. import org.apache.lucene.search.BooleanClause;   
  121. import org.apache.lucene.search.IndexSearcher;   
  122. import org.apache.lucene.search.Query;   
  123. import org.apache.lucene.search.ScoreDoc;   
  124. import org.apache.lucene.search.TopDocCollector;   
  125. import org.apache.lucene.search.highlight.Highlighter;   
  126. import org.apache.lucene.search.highlight.QueryScorer;   
  127. import org.apache.lucene.search.highlight.SimpleFragmenter;   
  128. import org.apache.lucene.search.highlight.SimpleHTMLFormatter;   
  129.   
  130. import test.TestLuceneHighlighter2;   
  131.   
  132.   
  133. /**  
  134.  * 高亮显示检索结果  
  135.  * Lucene 2.3.2 + Highlighter 2.2.0 的分页+高亮显示代码例子.<br>  
  136.  * Lucene和Highlighter不是最新版本可以升级。  
  137.  */  
  138. public class QueryHighLighter {   
  139.   
  140.     private static final String FIELD_TITLE = "title";   
  141.   
  142.     private static final String FIELD_BODY = "body";   
  143.   
  144.     public synchronized Analyzer getAnalyzer() {   
  145.         return new PaodingAnalyzer();// 此处使用"庖丁解牛"分词法,另外一种是中科院分词法   
  146.     }   
  147.   
  148.     public String test(String queryString, int begin, int number) {   
  149.         StringBuffer sb = new StringBuffer();   
  150.         IndexSearcher isearcher = null;   
  151.         try {   
  152.             isearcher = new IndexSearcher("D:\\save");   
  153.             /* 下面这个表示要同时搜索这两个域,而且只要一个域里面有满足我们搜索的内容就行 */  
  154.             BooleanClause.Occur[] clauses = { BooleanClause.Occur.SHOULD,   
  155.                     BooleanClause.Occur.SHOULD };   
  156.             TopDocCollector collector = new TopDocCollector(10);   
  157.             /*Query query = MultiFieldQueryParser.parse(queryString,  
  158.                     new String[] { FIELD_TITLE, FIELD_BODY }, clauses,  
  159.                     getAnalyzer());*/  
  160.             QueryParser queryParse = new QueryParser(FIELD_TITLE, getAnalyzer());      
  161.             Query query = queryParse.parse(queryString);     
  162.                
  163.             isearcher.search(query, collector);   
  164.             ScoreDoc[] hits = collector.topDocs().scoreDocs;   
  165.             // 用这个进行高亮显示,默认是<b>..</b>   
  166.             // 用这个指定<read>..</read>   
  167.             SimpleHTMLFormatter simpleHTMLFormatter = new SimpleHTMLFormatter("<b><font color='red'>""</font></b>");   
  168.             // 构造高亮   
  169.             // 指定高亮的格式   
  170.             // 指定查询评分   
  171.             Highlighter highlighter = new Highlighter(simpleHTMLFormatter, new QueryScorer(query));   
  172.             // 这个一般等于你要返回的,高亮的数据长度   
  173.             // 如果太小,则只有数据的开始部分被解析并高亮,且返回的数据也少   
  174.             // 太大,有时太浪费了。   
  175.             highlighter.setTextFragmenter(new SimpleFragmenter(Integer.MAX_VALUE));   
  176.             for (int i = begin; i < hits.length && i < begin + number; i++) {   
  177.                 Document doc = isearcher.doc(hits[i].doc);   
  178.                 String value = doc.get(FIELD_TITLE);   
  179.                 String value2 = doc.get(FIELD_BODY);   
  180.                 // 有三个参数   
  181.                 // 分析器   
  182.                 // 要解析的字段名   
  183.                 // 要解析的数据   
  184.                 //System.out.println(highlighter.getBestFragment(getAnalyzer(),   
  185.                 //      FIELD_TITLE, doc.get(FIELD_TITLE)));   
  186.                    
  187.                 if (value != null) {   
  188.                     TokenStream tokenStream = getAnalyzer().tokenStream(FIELD_TITLE, new StringReader(value));   
  189.                     String str = highlighter.getBestFragment(tokenStream, value);   
  190.                     sb.append("<li><li>").append(str).append("<br/>");   
  191.                     System.out.println(str);   
  192.                 }    
  193.                    
  194.             }   
  195.         } catch (Exception e) {   
  196.             e.printStackTrace();   
  197.         } finally {   
  198.             if (isearcher != null) {   
  199.                 try {   
  200.                     isearcher.close();   
  201.                 } catch (Exception e) {   
  202.                     e.printStackTrace();   
  203.                 }   
  204.             }   
  205.         }   
  206.         return sb.toString();   
  207.     }   
  208.        
  209.     public static void main(String[] args){   
  210.         TestLuceneHighlighter2 t = new TestLuceneHighlighter2();   
  211.         String queryString = "中华人民共和国";   
  212.         int begin = 0;   
  213.         int number = 10;   
  214.         t.test(queryString, begin, number);   
  215.     }   
  216.   
  217. }   
  218.     
package demo;   
  
import java.io.StringReader;   
  
import net.paoding.analysis.analyzer.PaodingAnalyzer;   
  
import org.apache.lucene.analysis.Analyzer;   
import org.apache.lucene.analysis.TokenStream;   
import org.apache.lucene.document.Document;   
import org.apache.lucene.queryParser.QueryParser;   
import org.apache.lucene.search.BooleanClause;   
import org.apache.lucene.search.IndexSearcher;   
import org.apache.lucene.search.Query;   
import org.apache.lucene.search.ScoreDoc;   
import org.apache.lucene.search.TopDocCollector;   
import org.apache.lucene.search.highlight.Highlighter;   
import org.apache.lucene.search.highlight.QueryScorer;   
import org.apache.lucene.search.highlight.SimpleFragmenter;   
import org.apache.lucene.search.highlight.SimpleHTMLFormatter;   
  
import test.TestLuceneHighlighter2;   
  
  
/**  
 * 高亮显示检索结果  
 * Lucene 2.3.2 + Highlighter 2.2.0 的分页+高亮显示代码例子.<br>  
 * Lucene和Highlighter不是最新版本可以升级。  
 */  
public class QueryHighLighter {   
  
    private static final String FIELD_TITLE = "title";   
  
    private static final String FIELD_BODY = "body";   
  
    public synchronized Analyzer getAnalyzer() {   
        return new PaodingAnalyzer();// 此处使用"庖丁解牛"分词法,另外一种是中科院分词法   
    }   
  
    public String test(String queryString, int begin, int number) {   
        StringBuffer sb = new StringBuffer();   
        IndexSearcher isearcher = null;   
        try {   
            isearcher = new IndexSearcher("D:\\save");   
            /* 下面这个表示要同时搜索这两个域,而且只要一个域里面有满足我们搜索的内容就行 */  
            BooleanClause.Occur[] clauses = { BooleanClause.Occur.SHOULD,   
                    BooleanClause.Occur.SHOULD };   
            TopDocCollector collector = new TopDocCollector(10);   
            /*Query query = MultiFieldQueryParser.parse(queryString,  
                    new String[] { FIELD_TITLE, FIELD_BODY }, clauses,  
                    getAnalyzer());*/  
            QueryParser queryParse = new QueryParser(FIELD_TITLE, getAnalyzer());      
            Query query = queryParse.parse(queryString);     
               
            isearcher.search(query, collector);   
            ScoreDoc[] hits = collector.topDocs().scoreDocs;   
            // 用这个进行高亮显示,默认是<b>..</b>   
            // 用这个指定<read>..</read>   
            SimpleHTMLFormatter simpleHTMLFormatter = new SimpleHTMLFormatter("<b><font color='red'>", "</font></b>");   
            // 构造高亮   
            // 指定高亮的格式   
            // 指定查询评分   
            Highlighter highlighter = new Highlighter(simpleHTMLFormatter, new QueryScorer(query));   
            // 这个一般等于你要返回的,高亮的数据长度   
            // 如果太小,则只有数据的开始部分被解析并高亮,且返回的数据也少   
            // 太大,有时太浪费了。   
            highlighter.setTextFragmenter(new SimpleFragmenter(Integer.MAX_VALUE));   
            for (int i = begin; i < hits.length && i < begin + number; i++) {   
                Document doc = isearcher.doc(hits[i].doc);   
                String value = doc.get(FIELD_TITLE);   
                String value2 = doc.get(FIELD_BODY);   
                // 有三个参数   
                // 分析器   
                // 要解析的字段名   
                // 要解析的数据   
                //System.out.println(highlighter.getBestFragment(getAnalyzer(),   
                //      FIELD_TITLE, doc.get(FIELD_TITLE)));   
                   
                if (value != null) {   
                    TokenStream tokenStream = getAnalyzer().tokenStream(FIELD_TITLE, new StringReader(value));   
                    String str = highlighter.getBestFragment(tokenStream, value);   
                    sb.append("<li><li>").append(str).append("<br/>");   
                    System.out.println(str);   
                }    
                   
            }   
        } catch (Exception e) {   
            e.printStackTrace();   
        } finally {   
            if (isearcher != null) {   
                try {   
                    isearcher.close();   
                } catch (Exception e) {   
                    e.printStackTrace();   
                }   
            }   
        }   
        return sb.toString();   
    }   
       
    public static void main(String[] args){   
        TestLuceneHighlighter2 t = new TestLuceneHighlighter2();   
        String queryString = "中华人民共和国";   
        int begin = 0;   
        int number = 10;   
        t.test(queryString, begin, number);   
    }   
  
}  

package demo;

import java.io.StringReader;

import net.paoding.analysis.analyzer.PaodingAnalyzer;

import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.analysis.TokenStream;
import org.apache.lucene.document.Document;
import org.apache.lucene.queryParser.QueryParser;
import org.apache.lucene.search.BooleanClause;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.ScoreDoc;
import org.apache.lucene.search.TopDocCollector;
import org.apache.lucene.search.highlight.Highlighter;
import org.apache.lucene.search.highlight.QueryScorer;
import org.apache.lucene.search.highlight.SimpleFragmenter;
import org.apache.lucene.search.highlight.SimpleHTMLFormatter;

import test.TestLuceneHighlighter2;


/**
 * 高亮显示检索结果
 * Lucene 2.3.2 + Highlighter 2.2.0 的分页+高亮显示代码例子.<br>
 * Lucene和Highlighter不是最新版本可以升级。
 */
public class QueryHighLighter {

	private static final String FIELD_TITLE = "title";

	private static final String FIELD_BODY = "body";

	public synchronized Analyzer getAnalyzer() {
		return new PaodingAnalyzer();// 此处使用"庖丁解牛"分词法,另外一种是中科院分词法
	}

	public String test(String queryString, int begin, int number) {
		StringBuffer sb = new StringBuffer();
		IndexSearcher isearcher = null;
		try {
			isearcher = new IndexSearcher("D:\\save");
			/* 下面这个表示要同时搜索这两个域,而且只要一个域里面有满足我们搜索的内容就行 */
			BooleanClause.Occur[] clauses = { BooleanClause.Occur.SHOULD,
					BooleanClause.Occur.SHOULD };
			TopDocCollector collector = new TopDocCollector(10);
			/*Query query = MultiFieldQueryParser.parse(queryString,
					new String[] { FIELD_TITLE, FIELD_BODY }, clauses,
					getAnalyzer());*/
			QueryParser queryParse = new QueryParser(FIELD_TITLE, getAnalyzer());   
			Query query = queryParse.parse(queryString);  
			
			isearcher.search(query, collector);
			ScoreDoc[] hits = collector.topDocs().scoreDocs;
			// 用这个进行高亮显示,默认是<b>..</b>
			// 用这个指定<read>..</read>
			SimpleHTMLFormatter simpleHTMLFormatter = new SimpleHTMLFormatter("<b><font color='red'>", "</font></b>");
			// 构造高亮
			// 指定高亮的格式
			// 指定查询评分
			Highlighter highlighter = new Highlighter(simpleHTMLFormatter, new QueryScorer(query));
			// 这个一般等于你要返回的,高亮的数据长度
			// 如果太小,则只有数据的开始部分被解析并高亮,且返回的数据也少
			// 太大,有时太浪费了。
			highlighter.setTextFragmenter(new SimpleFragmenter(Integer.MAX_VALUE));
			for (int i = begin; i < hits.length && i < begin + number; i++) {
				Document doc = isearcher.doc(hits[i].doc);
				String value = doc.get(FIELD_TITLE);
				String value2 = doc.get(FIELD_BODY);
				// 有三个参数
				// 分析器
				// 要解析的字段名
				// 要解析的数据
				//System.out.println(highlighter.getBestFragment(getAnalyzer(),
				//		FIELD_TITLE, doc.get(FIELD_TITLE)));
				
				if (value != null) {
					TokenStream tokenStream = getAnalyzer().tokenStream(FIELD_TITLE, new StringReader(value));
					String str = highlighter.getBestFragment(tokenStream, value);
					sb.append("<li><li>").append(str).append("<br/>");
					System.out.println(str);
				} 
				
			}
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			if (isearcher != null) {
				try {
					isearcher.close();
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		}
		return sb.toString();
	}
	
	public static void main(String[] args){
		TestLuceneHighlighter2 t = new TestLuceneHighlighter2();
		String queryString = "中华人民共和国";
		int begin = 0;
		int number = 10;
		t.test(queryString, begin, number);
	}

}
  


附加上传net\paoding\analysis\Constants.java便于理解参数设置:

Java代码 复制代码
  1. package net.paoding.analysis;      
  2.      
  3. import java.util.HashMap;      
  4. import java.util.Map;      
  5. import java.util.Properties;      
  6.      
  7. /**    
  8.  *     
  9.  * @author Zhiliang Wang [qieqie.wang@gmail.com]    
  10.  *     
  11.  * @since 2.0.0    
  12.  */     
  13. </strong
    分享到:
    评论
    1 楼 yuqihengsheng 2012-07-11  
    strong  很细

相关推荐

Global site tag (gtag.js) - Google Analytics