全文检索 Lucene(4)
经过了前面几篇文章的学习,我们基本上可以适用Lucene来开发我们的站内搜索应用了。但是观察一下目前的主流的搜索引擎,我们会发现查询结果会有高亮的显示效果。所以,今天我们就来学习一下,给Lucene添加以下高亮的显示效果。
必备基础
我们这次的分享,代码还是基于前面的内容。所以还请仔细阅读前面的文章。
高亮原理
一般来说,高亮会显示在网页上,所以我们只需要把查询到的结果,词语的外边包裹一层HTML的font标签,来达到高亮的效果。
实际案例
/**
* 带有高亮显示的分页查询
*
* @param queryString
* 待查询的字符串
* @param firstResult
* 开始位置
* @param maxResult
* 页面记录最大数量
* @return
*/
public Page searchWithHighLighter(String queryString, int firstResult, int maxResult) {
try {
// 1.queryString -->>Query
String[] queryFields = new String[] { "title", "content" };
Analyzer analyzer = new StandardAnalyzer();
analyzer.setVersion(Version.LUCENE_6_0_0.LUCENE_6_1_0);
QueryParser queryParser = new MultiFieldQueryParser(queryFields, analyzer);
Query query = queryParser.parse(queryString);
// 2. 查询,得到topDocs
IndexSearcher indexSearcher = LuceneUtils.getIndexSearcher();
TopDocs topDocs = indexSearcher.search(query, 100);
// 3.处理结果并返回
int totalHits = topDocs.totalHits;
ScoreDoc[] scoreDocs = topDocs.scoreDocs;
List<Article> articles = new ArrayList<Article>();
int upperBound = (firstResult + maxResult) < scoreDocs.length ? (firstResult + maxResult)
: scoreDocs.length;
firstResult = (firstResult >= 0 ? firstResult : 0);
// -------------------------------高亮操作
Formatter formatter = new SimpleHTMLFormatter("<font color='red'>", "</font>");
Scorer scorer = new QueryScorer(query);
Highlighter highLighter = new Highlighter(formatter, scorer);
// 第二个参数默认为100,即指定显示的摘要的文字的大小
Fragmenter fragmenter = new SimpleFragmenter(100);
// ---------------------------------高亮配置结束
highLighter.setTextFragmenter(fragmenter);
for (int i = firstResult; i < upperBound; i++) {
ScoreDoc scoreDoc = scoreDocs[i];
Document doc = indexSearcher.doc(scoreDoc.doc);
// 监测有没有目标词
String text = highLighter.getBestFragment(new StandardAnalyzer(), "content", doc.get("content"));
// 这里的操作和3.0版本的不一致
String content = "";
if (text != null) {
TokenStream tokenStream = analyzer.tokenStream("content", new StringReader(doc.get("content")));
content = highLighter.getBestFragment(tokenStream, doc.get("content"));
}
Article a = ArticleDocumentUtils.document2Article(doc, content);
articles.add(a);
}
LuceneUtils.closeIndexSearcher(indexSearcher);
// 处理查询结果,返回一个封装好的页面对象
Page<Article> page = new Page();
page.setLists(articles);
page.setTotalResults(totalHits);
return page != null ? page : null;
} catch (Exception e) {
throw new RuntimeException("ArticleIndexDao-->> search方法出错!\n" + e);
}
}
简化操作的一个工具方法
ArticleDocumentUtils.document2Article(doc, content);
具体代码如下:
/**
* 高亮处理过的文本,转换为Article对象
*
* @param document
* @param replaceText
* @return
*/
public static Article document2Article(Document document, String replaceText) {
Article a = new Article();
a.setId(Integer.parseInt(document.get("id")));
a.setTitle(document.get("title"));
a.setContent(replaceText);
return a != null ? a : null;
}
输出结果
-------------------查询到的总记录数----------------------17
Article [id=4, title=我的Save测试案例4, content=<font color='red'>Junit</font>是一个很好的测试工具,我们可以在这工具的帮助下下写出健壮性很强的代码!16]
Article [id=5, title=我的Save测试案例5, content=<font color='red'>Junit</font>是一个很好的测试工具,我们可以在这工具的帮助下下写出健壮性很强的代码!25]
Article [id=6, title=我的Save测试案例6, content=<font color='red'>Junit</font>是一个很好的测试工具,我们可以在这工具的帮助下下写出健壮性很强的代码!36]
Article [id=7, title=我的Save测试案例7, content=<font color='red'>Junit</font>是一个很好的测试工具,我们可以在这工具的帮助下下写出健壮性很强的代码!49]
Article [id=8, title=我的Save测试案例8, content=<font color='red'>Junit</font>是一个很好的测试工具,我们可以在这工具的帮助下下写出健壮性很强的代码!64]
Article [id=9, title=我的Save测试案例9, content=<font color='red'>Junit</font>是一个很好的测试工具,我们可以在这工具的帮助下下写出健壮性很强的代码!81]
Article [id=0, title=我的Save测试案例0, content=<font color='red'>Junit</font>是一个很好的测试工具,我们可以在这工具的帮助下下写出健壮性很强的代码!0]
Article [id=1, title=我的Save测试案例1, content=<font color='red'>Junit</font>是一个很好的测试工具,我们可以在这工具的帮助下下写出健壮性很强的代码!1]
Article [id=2, title=我的Save测试案例2, content=<font color='red'>Junit</font>是一个很好的测试工具,我们可以在这工具的帮助下下写出健壮性很强的代码!4]
Article [id=3, title=我的Save测试案例3, content=<font color='red'>Junit</font>是一个很好的测试工具,我们可以在这工具的帮助下下写出健壮性很强的代码!9]
案例解析
高亮器设置
// -------------------------------高亮操作
Formatter formatter = new SimpleHTMLFormatter("<font color='red'>", "</font>");
Scorer scorer = new QueryScorer(query);
Highlighter highLighter = new Highlighter(formatter, scorer);
// 第二个参数默认为100,即指定显示的摘要的文字的大小
Fragmenter fragmenter = new SimpleFragmenter(100);
highLighter.setTextFragmenter(fragmenter);
// ---------------------------------高亮配置结束
这基本上不会变动,所以我们拷贝一下就可以放到别的地方进行使用。很方便。
索引值包装并处理到实体结果集中
for (int i = firstResult; i < upperBound; i++) {
ScoreDoc scoreDoc = scoreDocs[i];
Document doc = indexSearcher.doc(scoreDoc.doc);
// 监测有没有目标词
String text = highLighter.getBestFragment(new StandardAnalyzer(), "content", doc.get("content"));
// 这里的操作和3.0版本的不一致
String content = "";
// 如果有索引值信息,就把包裹完高亮的结果返回
if (text != null) {
TokenStream tokenStream = analyzer.tokenStream("content", new StringReader(doc.get("content")));
content = highLighter.getBestFragment(tokenStream, doc.get("content"));
}
// 将高亮结果封装到结果集中,然而这并不影响索引库中的实际信息的值。属于视图层面的变化。
Article a = ArticleDocumentUtils.document2Article(doc, content);
articles.add(a);
}
LuceneUtils.closeIndexSearcher(indexSearcher);
总结
高亮显示对于一个站内搜索系统而言,可以起到画龙点睛的作用。虽然很简单,但是我们仍然要好好的设计,来打造一个优雅的搜索系统。
全文检索 Lucene(4)的更多相关文章
- 全文检索 Lucene(3)
看完前两篇博客之后,想必大家对于Lucene的使用都有了一个比较清晰的认识了.如果对Lucene的知识点还是有点模糊的话,个人建议还是先看看这两篇文章. 全文检索 Lucene(1) 全文检索 Luc ...
- 全文检索Lucene (2)
接着全文检索Lucene (1) . 下面我们来深入的研究一下,如何使用Lucene! 从全文检索Lucene (1)中我们可以看出,Lucene就好比一个双向的工作流,一方面是对索引库的维护,另一方 ...
- Lucene 全文检索 Lucene的使用
Lucene 全文检索 Lucene的使用 一.简介: 参考百度百科: http://baike.baidu.com/link?url=eBcEVuUL3TbUivRvtgRnMr1s44nTE7 ...
- 全文检索--Lucene & ElasticSearch
全文检索--Lucene 2.1 全文检索和以前高级查询的比较 1.高级查询 缺点:1.like让数据库索引失效 2.每次查询都是查询数据库 ,如果访问的人比较多,压力也是比较大 2.全文检索框架:A ...
- [全文检索]Lucene基础入门.
本打算直接来学习Solr, 现在先把Lucene的只是捋一遍. 本文内容: 1. 搜索引擎的发展史 2. Lucene入门 3. Lucene的API详解 4. 索引调优 5. Lucene搜索结果排 ...
- 全文检索Lucene (1)
Lucene是apache开源的一个全文检索框架,很是出名.今天先来分享一个类似于HelloWorld级别的使用. 工作流程 依赖 我们要想使用Lucene,那就得先引用人家的jar包了.下面列举一下 ...
- 全文检索-Lucene.net
Lucene.net是Lucene的.net移植版本,在较早之前是比较受欢迎的一个开源的全文检索引擎开发包,即它不是一个完整的全文检索引擎,而是一个全文检索引擎的架构,提供了完整的查询引擎和索引引擎. ...
- 全文检索Lucene框架---查询索引
一. Lucene索引库查询 对要搜索的信息创建Query查询对象,Lucene会根据Query查询对象生成最终的查询语法,类似关系数据库Sql语法一样Lucene也有自己的查询语法,比如:“name ...
- ]NET Core Lucene.net和PanGu分词实现全文检索
Lucene.net和PanGu分词实现全文检索 Lucene.net(4.8.0) 学习问题记录五: JIEba分词和Lucene的结合,以及对分词器的思考 前言:目前自己在做使用Lucene. ...
随机推荐
- Struts2--二次提交
在Struts2中,使用token的方式来防止二次提交.并且在默认的拦截器栈中提供了两个默认拦截器Token Interceptor和Token Session Interceptor.必须要在for ...
- 洛谷4月月赛R1
T1.题目大意:n个人站成一排,有m个团队,每个人有且属于一个团队,可以让若干个人出队,任意交换这些人的位置后再站回去,问要让所有同一团队的人连续地站在一起,至少要出队几个.(n<=10^5,m ...
- 【Rain in ACStar HDU-3340】
·你正从AC星球返回,天又下起凸包雨,只好到线段树下躲雨. ·英文题,述大意: 一个竖直平面的美丽天空,会下凸包雨.凸包雨指的是边数为3~6的多边形,并且每一个它都遵守一个神奇定律,那就是 ...
- AtCoder Beginner Contest 071 D - Coloring Dominoes
Problem Statement We have a board with a 2×N grid. Snuke covered the board with N dominoes without o ...
- ubuntu 安装 WPS for Linux(ubuntu)字体配置(字体缺失解决办法)及卸载libreoffice
从官网下载安装wps for Linux sudo dpkg -i wps-office_10.1.0.5672~a21_amd64.deb 启动WPS for Linux后,出现提示"系统 ...
- Linux查看日志方法总结(1)
注:日志文件为:test.log 1.tail -f test.log 查看当前打印的日志(平时就知道这方法!打印出的长度有限制.) 以下为网上搜集的: 2.先必须了解两个最基本的命令: tail ...
- Python3玩转儿 机器学习(4)
jupyternotebook 的使用方法¶ 最基本的使用¶ In [1]: 1+2 Out[1]: 3 菜单树¶ File¶ |------> New Notebook --- ...
- 我的博客地址和github地址
博客地址 http://www.cnblogs.com/sjzsjzsjz/ github地址 https://github.com/sjzsjzsjz
- java如何获得数据库表中各字段的字段名
public class TestDemo { public static Connection getConnection() { Connection conn = null; try { Cla ...
- JVM内部原理
这篇文章详细描述了Java虚拟机的内在结构.下面这张图来自<The Java Virtual Machine Specification Java SE 7 Edition>,它展示了一个 ...