经过了前面几篇文章的学习,我们基本上可以适用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)的更多相关文章

  1. 全文检索 Lucene(3)

    看完前两篇博客之后,想必大家对于Lucene的使用都有了一个比较清晰的认识了.如果对Lucene的知识点还是有点模糊的话,个人建议还是先看看这两篇文章. 全文检索 Lucene(1) 全文检索 Luc ...

  2. 全文检索Lucene (2)

    接着全文检索Lucene (1) . 下面我们来深入的研究一下,如何使用Lucene! 从全文检索Lucene (1)中我们可以看出,Lucene就好比一个双向的工作流,一方面是对索引库的维护,另一方 ...

  3. Lucene 全文检索 Lucene的使用

    Lucene  全文检索  Lucene的使用 一.简介: 参考百度百科: http://baike.baidu.com/link?url=eBcEVuUL3TbUivRvtgRnMr1s44nTE7 ...

  4. 全文检索--Lucene & ElasticSearch

    全文检索--Lucene 2.1 全文检索和以前高级查询的比较 1.高级查询 缺点:1.like让数据库索引失效 2.每次查询都是查询数据库 ,如果访问的人比较多,压力也是比较大 2.全文检索框架:A ...

  5. [全文检索]Lucene基础入门.

    本打算直接来学习Solr, 现在先把Lucene的只是捋一遍. 本文内容: 1. 搜索引擎的发展史 2. Lucene入门 3. Lucene的API详解 4. 索引调优 5. Lucene搜索结果排 ...

  6. 全文检索Lucene (1)

    Lucene是apache开源的一个全文检索框架,很是出名.今天先来分享一个类似于HelloWorld级别的使用. 工作流程 依赖 我们要想使用Lucene,那就得先引用人家的jar包了.下面列举一下 ...

  7. 全文检索-Lucene.net

    Lucene.net是Lucene的.net移植版本,在较早之前是比较受欢迎的一个开源的全文检索引擎开发包,即它不是一个完整的全文检索引擎,而是一个全文检索引擎的架构,提供了完整的查询引擎和索引引擎. ...

  8. 全文检索Lucene框架---查询索引

    一. Lucene索引库查询 对要搜索的信息创建Query查询对象,Lucene会根据Query查询对象生成最终的查询语法,类似关系数据库Sql语法一样Lucene也有自己的查询语法,比如:“name ...

  9. ]NET Core Lucene.net和PanGu分词实现全文检索

    Lucene.net和PanGu分词实现全文检索 Lucene.net(4.8.0) 学习问题记录五: JIEba分词和Lucene的结合,以及对分词器的思考   前言:目前自己在做使用Lucene. ...

随机推荐

  1. 实验吧_程序逻辑问题(代码审计)&上传绕过

    一开始我先随便输入了几个账号名字进行测试,发现当输入的账号名为admin时会发生报错 经过测试果然是一个注入点 当拿到admin密码后发现根本没用,没办法另寻他路 审查元素时发现提示index.txt ...

  2. [SHOI 2011]双倍回文

    Description 题库链接 记一个字符串为 \(X\) ,它的倒置为 \(X^R\) .现在给你一个长度为 \(n\) 的字符串 \(S\) ,询问其最长的形同 \(XX^RXX^R\) 的子串 ...

  3. ●CodeForces 698C LRU

    题链: http://codeforces.com/problemset/problem/698/C题解.1: 概率dp,状压dp 棒棒哒题解:https://www.cnblogs.com/liu- ...

  4. Ubuntu 16.04 Vim安装及配置

    安装VIM 默认已经安装了VIM-tiny acewu@acewu-computer:~$ locate vi | grep 'vi$' |xargs ls -al lrwxrwxrwx 1 root ...

  5. Entity Framework DBContext 增删改查深度解析

    Entity Framework DBContext 增删改查深度解析 有一段时间没有更新博客了,赶上今天外面下雨,而且没人约球,打算把最近对Entity Framework DBContext使用的 ...

  6. centos下 apache+mysql+php的安装

    一.安装 MySQL 首先来进行 MySQL 的安装.打开超级终端,输入: [root@localhost ~]# yum install mysql mysql-server 安装完毕,让 MySQ ...

  7. springmvc上传文件方法及注意事项

    本文基于注解的配置,敬请留意  基于注解整合 一.springmvc为我们提供两种上传方式配置: org.springframework.web.multipart.commons.CommonsMu ...

  8. vim的基本介绍

    vim四种模式: 1.正常模式(Normal-mode) 当我们打开vim时就会进入到正常模式,这个时候是不能编辑的,一般用于浏览文件,包括复制,删除一些文本操作.我们可以通过键盘的上下左右来进行光标 ...

  9. SQL Server2008 安装失败后的解决办法

    SQL Server2008 安装不容易成功,或许用这种方法可能会安装成功.     首先,把电脑上的SQL Server2008 卸载干净 怎么卸载干净? 1.找到控制面板-->卸载程序--& ...

  10. C语言程序设计第三次作业——选择结构(1)

    一.改错题 1.题目计算f(x)的值:输入实数x,计算并输出下列分段函数f(x)的值,输出时保留1位小数. 源程序(有错误的程序): #include <stdio.h> int main ...