Lucene高亮显示详解
在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的文本内容(这里是指摘要文本)进行切分,找到与检索关键字相同或相似的词条,将高亮格式加入到摘要文本中,返回一个新 的、带有格式的摘要文本,在网页上就可以呈现高亮显示。
下面实现一个简单的例子,展示实现高亮显示的处理过程。
测试类如下所示:
package org.shirdrn.lucene.learn.highlight;
import java.io.IOException;
import java.io.StringReader;
import net.teamhot.lucene.ThesaurusAnalyzer;
import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.analysis.TokenStream;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import org.apache.lucene.index.CorruptIndexException;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.queryParser.ParseException;
import org.apache.lucene.queryParser.QueryParser;
import org.apache.lucene.search.Hits;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Query;
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;
public class MyHighLighter {
private String indexPath = "F://index";
private Analyzer analyzer;
private IndexSearcher searcher;
public MyHighLighter(){
analyzer = new ThesaurusAnalyzer();
}
public void createIndex() throws IOException { // 该方法建立索引
IndexWriter writer = new IndexWriter(indexPath,analyzer,true);
Document docA = new Document();
String fileTextA = "因为火烧云总是燃烧着消失在太阳冲下地平线的时刻,然后便是宁静的自然的天籁,没有谁会在这样的时光的镜片里伤感自语,因为灿烂给人以安静的舒适感。";
Field fieldA = new Field("contents", fileTextA, Field.Store.YES,Field.Index.TOKENIZED);
docA.add(fieldA);
Document docB = new Document();
String fileTextB = "因为带有以伤痕为代价的美丽风景总是让人不由地惴惴不安,紧接着袭面而来的抑或是病痛抑或是灾难,没有谁会能够安逸着恬然,因为模糊让人撕心裂肺地想呐喊。";
Field fieldB = new Field("contents", fileTextB, Field.Store.YES,Field.Index.TOKENIZED);
docB.add(fieldB);
Document docC = new Document();
String fileTextC = "我喜欢上了一个人孤独地行游,在梦与海洋的交接地带炽烈燃烧着。"+
"因为,一条孤独的鱼喜欢上了火焰的颜色,真是荒唐地不合逻辑。";
Field fieldC = new Field("contents", fileTextC, Field.Store.YES,Field.Index.TOKENIZED);
docC.add(fieldC);
writer.addDocument(docA);
writer.addDocument(docB);
writer.addDocument(docC);
writer.optimize();
writer.close();
}
public void search(String fieldName,String keyword) throws CorruptIndexException, IOException, ParseException{ // 检索的方法,并实现高亮显示
searcher = new IndexSearcher(indexPath);
QueryParser queryParse = new QueryParser(fieldName, analyzer); // 构造QueryParser,解析用户输入的检索关键字
Query query = queryParse.parse(keyword);
Hits hits = searcher.search(query);
for(int i=0;i<hits.length();i++){
Document doc = hits.doc(i);
String text = doc.get(fieldName);
SimpleHTMLFormatter simpleHTMLFormatter = new SimpleHTMLFormatter("<font color='red'>", "</font>");
Highlighter highlighter = new Highlighter(simpleHTMLFormatter,new QueryScorer(query));
highlighter.setTextFragmenter(new SimpleFragmenter(text.length()));
if (text != null) {
TokenStream tokenStream = analyzer.tokenStream(fieldName,new StringReader(text));
String highLightText = highlighter.getBestFragment(tokenStream, text);
System.out.println("★高亮显示第 "+(i+1) +" 条检索结果如下所示:");
System.out.println(highLightText);
}
}
searcher.close();
}
public static void main(String[] args) { // 测试主函数
MyHighLighter mhl = new MyHighLighter();
try {
mhl.createIndex();
mhl.search("contents", "因为");
} catch (CorruptIndexException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (ParseException e) {
e.printStackTrace();
}
}
}
程序说明:
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网页中,就会高亮显示关键字“因为”,显示为红色。
Lucene高亮显示详解相关推荐
- Lucene DocValues详解
今天斗胆来试试DocValues,对于DocValues我想大家都不会觉得陌生,同时又不是非常熟悉,就是那种熟悉而又陌生的感觉. 一.docValues是什么鬼呢? DocValues在LUCENE- ...
- Lucene教程详解
欢迎关注微信账号:java那些事:csh624366188.每天一篇java相关的文章 注明:本文是由本人在开发有关基于lucene资源检索系统时的一点总结,其中一部分是自己根据开发过程自己总结的,也 ...
- Lucene分词详解
分词和查询都是以词项为基本单位,词项是词条化的结果.在Lucene中分词主要依靠Analyzer类解析实现.Analyzer类是一个抽象类,分词的具体规则是由子类实现的,所以对于不同的语言规则,要有不 ...
- Lucene索引详解
今天我给大家讲讲Lucene是如何索引文档的,索引文档就是把文档变成索引这种数据结构的过程. 文档是Lucene索引的基本单位,比文档更小的单位是字段,字段是文档的一部分,每个字段由名称.类型和取值组 ...
- 【实现平台搜索功能】lucene全文搜索引擎模块的简单使用,内含原理详解
0.Lucene介绍 lunece是一项全文检索技术,是apache下的一个开源全文检索引擎工具包,提供了完整的查询引擎和索引引擎,部分文本分析引擎.需要实现全文检索的一般功能的时候是够用的了. 数据 ...
- echart的关系图高亮_echarts鼠标覆盖高亮显示节点及关系名称详解
js代码,使用了jquery和echarts.js,用的是源代码那版,因为待会要进源代码里修改-- 其实js代码和echart官网demo的代码完全没区别-- 普通的力图设置,只要加上focusNod ...
- Lucene打分规则与Similarity模块详解
https://my.oschina.net/BreathL/blog/51498 搜索排序结果的控制 Lucnen作为搜索引擎中,应用最为广泛和成功的开源框架,它对搜索结果的排序,有一套十分完整的机 ...
- lucene.NET详细使用与优化详解
lucene.NET详细使用与优化详解 http://www.cnblogs.com/qq4004229/archive/2010/05/21/1741025.html http://www.shan ...
- Lucene于搜索引擎技术(Analysis包详解)
Analysis包分析 算法和数据结构分析: 由于Analysis包比较简单,不详述了! 算法:基于机械分词 1-gram,2-gram,HMM(如果使用ICTCLAS接口的话) 数据结构:部分源码用 ...
最新文章
- 【 C 】经典抽象数据类型(ADT)之内存分配
- java web中中文乱码问题汇总
- c语言数组将素数放在前部,m个人的成绩存放在score数组中,请编写函数fun(),它的功能是将高于平均分的人数作为函数值返回,将_开卷宝...
- VTK:几何对象之Pyramid
- hotmail在outlook2007中的设置
- jq 自动滑动轮换(向后插入小块)
- 交互(python 版)
- 动态规划uva1347
- 【less-24】基于SQLI的二次注入
- webpack入门1
- Python列表和元组:[] ()
- hudson--插件管理
- 文件系统的设计与实现(操作系统课程设计)
- Kindle for PC: 优雅的 PDF 阅读器工具
- 卸载一个游戏计算机里还有文件,如何处理pc游戏卸载后留下的残余文件?
- Qt编写安防视频监控系统25-离线地图
- CRM系统慢慢转为企业微信SCRM
- 用git clone命令从gitlab上拉取公司项目操作步骤
- 【hihocoder1082】然而沼跃鱼早就看穿了一切——字符串
- 基于2.4GHz射频NRF24L01模块的智能家居项目总结