Lucene高亮显示详解

来源:互联网 发布:nginx luajit 编辑:程序博客网 时间:2024/04/27 23:20

分类: lucene 561人阅读 评论(0)收藏 举报
lucenestringquerygooglehtml百度

在Lucene的org.apache.lucene.search.highlight包中提供了关于高亮显示检索关键字的工具。使用百度、 Google搜索的时候,检索结果显示的时候,在摘要中实现与关键字相同的词条进行高亮显示,百度和Google指定红色高亮显示。

有了Lucene提供的高亮显示的工具,可以很方便地实现高亮显示的功能。

高亮显示,就是根据用户输入的检索关键字,检索找到该关键字对应的检索结果文件,提取对应于该文件的摘要文本,然后根据设置的高亮格式,将格式写入到摘要文本中对应的与关键字相同或相似的词条上,在网页上显示出来,该摘要中的与关键字有关的文本就会以高亮的格式显示出来。

Lucene中org.apache.lucene.search.highlight.SimpleHTMLFormatter类可以构造一个高亮格式,这是最简单的构造方式,例如:

SimpleHTMLFormatter simpleHTMLFormatter = new SimpleHTMLFormatter("<font color='red'>", "</font>");

构造方法声明为public SimpleHTMLFormatter(String preTag, String postTag),因为这种高亮格式是依赖于网页文件的,HTML文件中是以标记(tag)来标识的,即存在一个preTag和一个postTag。

上面构造的高亮格式是摘要中出现的关键字使用红色来显示,区分其它文本。

通过构造好的高亮格式对象,来构造一个org.apache.lucene.search.highlight.Highlighter实例,然后根据对检索结果得到的Field的文本内容(这里是指摘要文本)进行切分,找到与检索关键字相同或相似的词条,将高亮格式加入到摘要文本中,返回一个新的、带有格式的摘要文本,在网页上就可以呈现高亮显示。

下面实现一个简单的例子,展示实现高亮显示的处理过程。

测试类如下所示:

 

[java] view plaincopyprint?
  1. package org.shirdrn.lucene.learn.highlight;  
  2.   
  3. import java.io.IOException;  
  4. import java.io.StringReader;  
  5.   
  6. import net.teamhot.lucene.ThesaurusAnalyzer;  
  7.   
  8. import org.apache.lucene.analysis.Analyzer;  
  9. import org.apache.lucene.analysis.TokenStream;  
  10. import org.apache.lucene.document.Document;  
  11. import org.apache.lucene.document.Field;  
  12. import org.apache.lucene.index.CorruptIndexException;  
  13. import org.apache.lucene.index.IndexWriter;  
  14. import org.apache.lucene.queryParser.ParseException;  
  15. import org.apache.lucene.queryParser.QueryParser;  
  16. import org.apache.lucene.search.Hits;  
  17. import org.apache.lucene.search.IndexSearcher;  
  18. import org.apache.lucene.search.Query;  
  19. import org.apache.lucene.search.highlight.Highlighter;  
  20. import org.apache.lucene.search.highlight.QueryScorer;  
  21. import org.apache.lucene.search.highlight.SimpleFragmenter;  
  22. import org.apache.lucene.search.highlight.SimpleHTMLFormatter;  
  23.   
  24. public class MyHighLighter {  
  25.   
  26. private String indexPath = "F://index";  
  27. private Analyzer analyzer;  
  28. private IndexSearcher searcher;  
  29.   
  30. public MyHighLighter(){  
  31.    analyzer = new ThesaurusAnalyzer();  
  32. }  
  33.   
  34. public void createIndex() throws IOException {   // 该方法建立索引   
  35.    IndexWriter writer = new IndexWriter(indexPath,analyzer,true);  
  36.    Document docA = new Document();  
  37.    String fileTextA = "因为火烧云总是燃烧着消失在太阳冲下地平线的时刻,然后便是宁静的自然的天籁,没有谁会在这样的时光的镜片里伤感自语,因为灿烂给人以安静的舒适感。";  
  38.    Field fieldA = new Field("contents", fileTextA, Field.Store.YES,Field.Index.TOKENIZED);  
  39.    docA.add(fieldA);   
  40.     
  41.    Document docB = new Document();  
  42.    String fileTextB = "因为带有以伤痕为代价的美丽风景总是让人不由地惴惴不安,紧接着袭面而来的抑或是病痛抑或是灾难,没有谁会能够安逸着恬然,因为模糊让人撕心裂肺地想呐喊。";  
  43.    Field fieldB = new Field("contents", fileTextB, Field.Store.YES,Field.Index.TOKENIZED);  
  44.    docB.add(fieldB);   
  45.     
  46.    Document docC = new Document();  
  47.    String fileTextC = "我喜欢上了一个人孤独地行游,在梦与海洋的交接地带炽烈燃烧着。"+  
  48.    "因为,一条孤独的鱼喜欢上了火焰的颜色,真是荒唐地不合逻辑。";  
  49.    Field fieldC = new Field("contents", fileTextC, Field.Store.YES,Field.Index.TOKENIZED);  
  50.    docC.add(fieldC);   
  51.     
  52.    writer.addDocument(docA);  
  53.    writer.addDocument(docB);  
  54.    writer.addDocument(docC);  
  55.    writer.optimize();  
  56.    writer.close();  
  57. }  
  58.   
  59. public void search(String fieldName,String keyword) throws CorruptIndexException, IOException, ParseException{   // 检索的方法,并实现高亮显示  
  60.    searcher = new IndexSearcher(indexPath);   
  61.    QueryParser queryParse = new QueryParser(fieldName, analyzer);     //   构造QueryParser,解析用户输入的检索关键字   
  62.    Query query = queryParse.parse(keyword);   
  63.    Hits hits = searcher.search(query);  
  64.    for(int i=0;i<hits.length();i++){  
  65.     Document doc = hits.doc(i);  
  66.     String text = doc.get(fieldName);  
  67.     SimpleHTMLFormatter simpleHTMLFormatter = new SimpleHTMLFormatter("<font color='red'>""</font>");      
  68.             Highlighter highlighter = new Highlighter(simpleHTMLFormatter,new QueryScorer(query));      
  69.             highlighter.setTextFragmenter(new SimpleFragmenter(text.length()));         
  70.             if (text != null) {      
  71.                 TokenStream tokenStream = analyzer.tokenStream(fieldName,new StringReader(text));      
  72.                 String highLightText = highlighter.getBestFragment(tokenStream, text);   
  73.                 System.out.println("★高亮显示第 "+(i+1) +" 条检索结果如下所示:");   
  74.                 System.out.println(highLightText);      
  75.             }   
  76.    }  
  77.    searcher.close();  
  78. }  
  79.   
  80.   
  81. public static void main(String[] args) {    // 测试主函数   
  82.    MyHighLighter mhl = new MyHighLighter();  
  83.    try {  
  84.     mhl.createIndex();  
  85.     mhl.search("contents""因为");  
  86.    } catch (CorruptIndexException e) {  
  87.     e.printStackTrace();  
  88.    } catch (IOException e) {  
  89.     e.printStackTrace();  
  90.    } catch (ParseException e) {  
  91.     e.printStackTrace();  
  92.    }  
  93. }  
  94.   
  95. }  

程序说明:

1、createIndex()方法:使用ThesaurusAnalyzer分析器为指定的文本建立索引。每个Document中都有一个 name为contents的Field。在实际应用中,可以再构造一一个name为path的Field,指定检索到的文件的路径(本地路径或者网络上的链接地址)

2、根据已经建好的索引库进行检索。这首先需要解析用户输入的检索关键字,使用QueryParser,必须与后台使用的分析器相同,否则不能保证解析得到的查询(由词条构造)Query检索到合理的结果集。

3、根据解析出来的Query进行检索,检索结果集保存在Hits中。遍历,提取每个满足条件的Document的内容,程序中直接把它的内容当作摘要内容,实现高亮显示。在实际应用中,应该对应着一个提取摘要(或者检索数据库得到检索关键字对应的结果集文件的摘要内容)的过程。有了摘要以后,就可以为摘要内容增加高亮格式。

4、如果提取结果集文件的前N个字符串作为摘要,只需要在 highlighter.setTextFragmenter(new SimpleFragmenter(text.length())); 中设置显示摘要的字数,这里显示全部的文本作为摘要。

运行程序,结果如下所示:

词库尚未被初始化,开始初始化词库.
初始化词库结束。用时:3906毫秒;
共添加195574个词语。
★高亮显示第 1 条检索结果如下所示:
<font color='red'>因为</font> 火烧云总是燃烧着消失在太阳冲下地平线的时刻,然后便是宁静的自然的天籁,没有谁会在这样的时光的镜片里伤感自语,<font color='red'>因为</font> 灿烂给人以安静的舒适感。
★高亮显示第 2 条检索结果如下所示:
<font color='red'>因为</font> 带有以伤痕为代价的美丽风景总是让人不由地惴惴不安,紧接着袭面而来的抑或是病痛抑或是灾难,没有谁会能够安逸着恬然,<font color='red'>因为</font> 模糊让人撕心裂肺地想呐喊。
★高亮显示第 3 条检索结果如下所示:
我喜欢上了一个人孤独地行游,在梦与海洋的交接地带炽烈燃烧着。<font color='red'>因为</font> ,一条孤独的鱼喜欢上了火焰的颜色,真是荒唐地不合逻辑。

上面的检索结果在HTML网页中,就会高亮显示关键字“因为”,显示为红色。

 

本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/Java2King/archive/2009/08/04/4407998.aspx

0 0
原创粉丝点击