首页java › Lucene+HighLighter高亮显示实例

Lucene+HighLighter高亮显示实例

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

使用前先下载相关的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. public class CreateIndex      
  20.           
  21.     public void createIndex() throws Exception      
  22.              
  23.         File surceFileDir new File(“D:\\save\\source”);      
  24.      
  25.              
  26.         File indexFileDir new File(“D:\\save”);      
  27.               
  28.         //Analyzer luceneAnalyzer new StandardAnalyzer();      
  29.         Analyzer luceneAnalyzer new PaodingAnalyzer();//使用庖丁解牛分词法      
  30.               
  31.         IndexWriter indexWriter new IndexWriter(indexFileDir, luceneAnalyzer, true);///参数isEmpty是false表示增量索引      
  32.         File[] sourceFextFiles surceFileDir.listFiles();      
  33.         long startTime new Date().getTime();      
  34.      
  35.         // 增加document到索引去      
  36.         for (int 0sourceFextFiles.length; i++)      
  37.             if (sourceFextFiles[i].isFile()      
  38.                     && sourceFextFiles[i].getName().endsWith(“.txt”))      
  39.                 System.out.println(“File  sourceFextFiles[i].getCanonicalPath() “正在被索引….”);      
  40.                 String temp FileReaderAll(sourceFextFiles[i].getCanonicalPath(), “GBK”);      
  41.                 System.out.println(temp);      
  42.                 Document document new Document();      
  43.                 Field FieldPath new Field(“path”sourceFextFiles[i].getPath(), Field.Store.YES, Field.Index.NO);      
  44.                 Field FieldBody new Field(“body”temp, Field.Store.YES, Field.Index.TOKENIZED, Field.TermVector.WITH_POSITIONS_OFFSETS);      
  45.                 Field FieldTitle new Field(“title”temp, Field.Store.YES, Field.Index.TOKENIZED, Field.TermVector.WITH_POSITIONS_OFFSETS);      
  46.                 document.add(FieldPath);      
  47.                 document.add(FieldBody);document.add(FieldTitle);      
  48.                 indexWriter.addDocument(document);      
  49.                  
  50.              
  51.         // optimize()方法是对索引进行优化      
  52.         indexWriter.optimize();      
  53.         indexWriter.close();      
  54.      
  55.         // 测试一下索引的时间      
  56.         long endTime new Date().getTime();      
  57.         System.out.println(“这花费了” (endTime startTime) ” 毫秒来把文档增加到索引里面去!”     
  58.                 indexFileDir.getPath());      
  59.          
  60.      
  61.     public static String FileReaderAll(String FileName, String charset)      
  62.             throws IOException      
  63.         BufferedReader reader new BufferedReader(new InputStreamReader(     
  64.                 new FileInputStream(FileName), charset));      
  65.         String line new String();      
  66.         String temp new String();      
  67.      
  68.         while ((line reader.readLine()) != null     
  69.             temp += line;      
  70.              
  71.         reader.close();      
  72.         return temp;      
  73.          
  74.      
  75.          
  76.     public static void main(String[] args)      
  77.         try      
  78.             new CreateIndex().createIndex();      
  79.         catch (Exception e)      
  80.             e.printStackTrace();      
  81.              
  82.      
  83.          
  84.      
  85.    

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

附加上传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. public class Constants      
  9.      
  10.          
  11.     public static final String DIC_HOME_CONFIG_FIRST “paoding.dic.home.config-first”     
  12.     public static final String DIC_HOME_CONFIG_FIRST_DEFAULT “system-env”     
  13.      
  14.          
  15.     public static final String ENV_PAODING_DIC_HOME “PAODING_DIC_HOME”    
  16.      
  17.     // ————————————————————-      
  18.          
  19.     public static final String DIC_HOME “paoding.dic.home”     
  20.     public static final String DIC_HOME_DEFAULT null     
  21.      
  22.     // ————————————————————-      
  23.     //      
  24.     public static final String DIC_CHARSET “paoding.dic.charset”     
  25.     public static final String DIC_CHARSET_DEFAULT “UTF-8″     
  26.      
  27.     // ————————————————————-      
  28.     // dictionaries which are skip      
  29.     public static final String DIC_SKIP_PREFIX “paoding.dic.skip.prefix”    
  30.     public static final String DIC_SKIP_PREFIX_DEFAULT “x-“     
  31.      
  32.     // ————————————————————-      
  33.     // chinese/cjk charactors that will not token      
  34.     public static final String DIC_NOISE_CHARACTOR “paoding.dic.noise-charactor”     
  35.     public static final String DIC_NOISE_CHARACTOR_DEFAULT “x-noise-charactor”     
  36.      
  37.     // ————————————————————-      
  38.     // chinese/cjk words that will not token      
  39.     public static final String DIC_NOISE_WORD “paoding.dic.noise-word”    
  40.     public static final String DIC_NOISE_WORD_DEFAULT “x-noise-word”     
  41.      
  42.     // ————————————————————-      
  43.     // unit words, like “ge”, “zhi”, …      
  44.     public static final String DIC_UNIT “paoding.dic.unit”     
  45.     public static final String DIC_UNIT_DEFAULT “x-unit”     
  46.      
  47.     // ————————————————————-      
  48.     // like “Wang”, “Zhang”, …      
  49.     public static final String DIC_CONFUCIAN_FAMILY_NAME “paoding.dic.confucian-family-name”     
  50.     public static final String DIC_CONFUCIAN_FAMILY_NAME_DEFAULT “x-confucian-family-name”     
  51.           
  52.     // ————————————————————-      
  53.     // like       
  54.     public static final String DIC_FOR_COMBINATORICS “paoding.dic.for-combinatorics”     
  55.     public static final String DIC_FOR_COMBINATORICS_DEFAULT “x-for-combinatorics”     
  56.      
  57.     // ————————————————————-      
  58.     // like       
  59.     public static final String DIC_DETECTOR_INTERVAL “paoding.dic.detector.interval”     
  60.     public static final String DIC_DETECTOR_INTERVAL_DEFAULT “60”     
  61.      
  62.     // ————————————————————-      
  63.     // like “default”, “max”, …      
  64.     public static final String ANALYZER_MODE “paoding.analyzer.mode”     
  65.     public static final String ANALYZER_MOE_DEFAULT “most-words”     
  66.      
  67.     // ————————————————————-      
  68.     //       
  69.     public static final String ANALYZER_DICTIONARIES_COMPILER “paoding.analyzer.dictionaries.compiler”     
  70.     public static final String ANALYZER_DICTIONARIES_COMPILER_DEFAULT null     
  71.      
  72.     // ————————————————————-      
  73.     private static final Mapmap new HashMap();      
  74.      
  75.     static      
  76.         map.put(DIC_HOME_CONFIG_FIRST, DIC_HOME_CONFIG_FIRST_DEFAULT);      
  77.         map.put(DIC_HOME, DIC_HOME_DEFAULT);      
  78.         map.put(DIC_CHARSET, DIC_CHARSET_DEFAULT);      
  79.         map.put(DIC_SKIP_PREFIX, DIC_SKIP_PREFIX_DEFAULT);      
  80.         map.put(DIC_NOISE_CHARACTOR, DIC_NOISE_CHARACTOR_DEFAULT);      
  81.         map.put(DIC_NOISE_WORD, DIC_NOISE_WORD_DEFAULT);      
  82.         map.put(DIC_UNIT, DIC_UNIT_DEFAULT);      
  83.         map.put(DIC_CONFUCIAN_FAMILY_NAME, DIC_CONFUCIAN_FAMILY_NAME_DEFAULT);     
  84.         map.put(DIC_FOR_COMBINATORICS, DIC_FOR_COMBINATORICS_DEFAULT);      
  85.         map.put(DIC_DETECTOR_INTERVAL, DIC_DETECTOR_INTERVAL_DEFAULT);      
  86.         map.put(ANALYZER_MODE, ANALYZER_MOE_DEFAULT);      
  87.         map.put(ANALYZER_DICTIONARIES_COMPILER, ANALYZER_DICTIONARIES_COMPILER_DEFAULT);      
  88.          
  89.      
  90.     //      
  91.     public static final String KNIFE_CLASS “paoding.knife.class.”     
  92.      
  93.     public static String getProperty(Properties p, String name)      
  94.         return p.getProperty(name, (String) map.get(name));      
  95.          
  96.   

发表评论

注意 - 你可以用以下 HTML tags and attributes:
<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>