全文检索 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. ...
随机推荐
- 剥掉层层外衣后的RPC是什么样子的?
RPC,全称为Remote Procedure Call(远程过程调用).通俗一点讲就是在本地调用远程服务器上的功能.实现远程调用至少需要满足以下几个条件: 1.网络通信 2.序列化与反序列化 3.反 ...
- [HNOI2001]软件开发
题目描述 某软件公司正在规划一项n天的软件开发计划,根据开发计划第i天需要ni个软件开发人员,为了提高软件开发人员的效率,公司给软件人员提供了很多的 服务,其中一项服务就是要为每个开发人员每天提供一块 ...
- ●POJ 1741 Tree
题链: http://poj.org/problem?id=1741题解: 树上点分治. 入门题,不多说了. 代码: #include<cstdio> #include<cstrin ...
- ●BZOJ 4518 [Sdoi2016]征途
题链: http://www.lydsy.com/JudgeOnline/problem.php?id=4518 题解: 斜率优化DP 首先看看最后答案的形式: 设a[i]为第i天走的距离,那么 $A ...
- kafka快速入门
一.kafka简介 kafka,ActiveMQ,RabbitMQ是当今最流行的分布式消息中间件,其中kafka在性能及吞吐量方面是三者中的佼佼者,不过最近查阅官网时,官方与它的定义为一个分布式流媒体 ...
- 如何在Google上下载高清原图
在我们学习和生活中常常一些高清图片作为相关的素材,比如制作PPT.写博文.制作视频都需要大量图片.我们常常会在百度上下载一些图片,但是百度上提供的图片存在很多问题:存在水印.清晰度不够等.而Googl ...
- VC++6.0的使用方法
VC++6.0的最基本使用方法,创建一个c++项目工程可参考:https://jingyan.baidu.com/article/8ebacdf0cbdb5749f75cd54a.html 这里面的操 ...
- seq2seq-chatbot:200 行代码实现聊天机器人
Chatbot in 200 lines of code CPU 跑不动 github:https://github.com/zsdonghao/seq2seq-chatbot 更多英文,中文聊天机器 ...
- jvm(一):总体概述
我们首先来了解一下jdk,jre,jvm的之间的关系 jvm用于运行字节码,如果我们仅仅用于运行java程序,仅部署jre即可,如果我们需要进行java开发则需要jdk环境 java结构内容: jav ...
- SSM项目搭建之配置文件
1.1 pom文件配置 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http:// ...