3.6 Lucene基本检索+关键词高亮+分页

3.2节我们已经运行了一个Lucene实现检索的小程序,这一节我们将以这个小程序为例,讲一下Lucene检索的基本步骤,同时介绍关键词高亮显示和分页返回结果这两个有用的技巧。

一、Lucene检索的基本步骤

 1 import java.nio.file.Paths;
 2 import java.io.*;
 3
 4 import org.apache.lucene.analysis.standard.StandardAnalyzer;
 5 import org.apache.lucene.document.Document;
 6 import org.apache.lucene.index.DirectoryReader;
 7 import org.apache.lucene.queryparser.classic.QueryParser;
 8 import org.apache.lucene.search.IndexSearcher;
 9 import org.apache.lucene.search.Query;
10 import org.apache.lucene.search.ScoreDoc;
11 import org.apache.lucene.search.TopDocs;
12 import org.apache.lucene.store.Directory;
13 import org.apache.lucene.store.FSDirectory;
14 import org.apache.lucene.util.Version;
15
16 /**
17  * @author csl
18  * @description:
19  * 依赖jar:Lucene-core,lucene-analyzers-common,lucene-queryparser
20  * 作用:使用索引搜索文件
21  */
22 public class Searcher {
23     public static Version luceneVersion = Version.LATEST;
24     /**
25      * 查询内容
26      */
27     public static String indexSearch(String keywords){
28         String res = "";
29         DirectoryReader reader = null;
30         try{
31 //            1、创建Directory
32              Directory directory = FSDirectory.open(Paths.get("index"));//在硬盘上生成Directory
33 //            2、创建IndexReader
34              reader = DirectoryReader.open(directory);
35 //            3、根据IndexReader创建IndexSearcher
36              IndexSearcher searcher =  new IndexSearcher(reader);
37 //            4、创建搜索的query
38 //            创建parse用来确定搜索的内容,第二个参数表示搜索的域
39              QueryParser parser = new QueryParser("content",new StandardAnalyzer());//content表示搜索的域或者说字段
40              Query query = parser.parse(keywords);//被搜索的内容
41 //            5、根据Searcher返回TopDocs
42              TopDocs tds = searcher.search(query, 20);//查询20条记录
43 //            6、根据TopDocs获取ScoreDoc
44              ScoreDoc[] sds = tds.scoreDocs;
45 //            7、根据Searcher和ScoreDoc获取搜索到的document对象
46              int cou=0;
47              for(ScoreDoc sd:sds){
48                  cou++;
49                  Document d = searcher.doc(sd.doc);
50 //                    8、根据document对象获取查询的字段值
51                  /**  查询结果中content为空,是因为索引中没有存储content的内容,需要根据索引path和name从原文件中获取content**/
52                  res+=cou+". "+d.get("path")+" "+d.get("name")+" "+d.get("content")+"\n";
53              }
54
55
56         }catch(Exception e){
57             e.printStackTrace();
58         }finally{
59             //9、关闭reader
60             try {
61                 reader.close();
62             } catch (IOException e) {
63                 e.printStackTrace();
64             }
65         }
66         return res;
67     }
68     public static void main(String[] args) throws IOException
69     {
70         System.out.println(indexSearch("你好")); //搜索的内容可以修改
71     }
72 }

Searcher

搜索的过程总的来说就是将词典及倒排表信息从索引中读出来,根据用户输入的查询语句合并倒排表,得到结果文档集并对文档进行打分的过程。

总结起来检索有以下以下五个步骤:

1. 打开IndexReader指向索引文件夹。

1 Directory directory = FSDirectory.open(Paths.get("index"));
2 IndexReader reader = DirectoryReader.open(directory);

IndexReader

这一步骤将磁盘上的索引信息读入内存。

2. 创建IndexSearcher准备进行搜索。

1 IndexSearcher searcher =  new IndexSearcher(reader);

IndexSearcher

IndexSearcher提供了两个非常重要的函数:

  • void setSimilarity(Similarity similarity),用户可以实现自己的Similarity对象,从而影响搜索过程的打分。
  • 一系列search函数,是搜索过程的关键,主要负责打分的计算和倒排表的合并。

3. 创建QueryParser解析查询语句生成查询对象。

1 QueryParser parser = new QueryParser("content",new StandardAnalyzer());//content表示搜索的域或者说字段
2 Query query = parser.parse(keywords);//被搜索的内容

QueryParser

解析分为两个过程:

  • 创建Analyer用来对查询语句进行词法分析和语言处理。
  • QueryParser调用parser进行语法分析,形成查询语法树,放到Query中。

4. IndexSearcher调用search对查询语法树Query进行搜索,得到结果集Topdocs。

1 //            5、根据Searcher返回TopDocs
2              TopDocs tds = searcher.search(query, 20);//查询20条记录
3 //            6、根据TopDocs获取ScoreDoc
4              ScoreDoc[] sds = tds.scoreDocs;

Search

该方法收集文档集合并计算打分。

5. 返回查询结果给用户。

1 int cou=0;
2              for(ScoreDoc sd:sds){
3                  cou++;
4                  Document d = searcher.doc(sd.doc);
5 //                    8、根据document对象获取查询的字段值
6                  /**  查询结果中content为空,是因为索引中没有存储content的内容,需要根据索引path和name从原文件中获取content**/
7                  res+=cou+". "+d.get("path")+" "+d.get("name")+" "+d.get("content")+"\n";
8              }

Document

在返回查询结果给用户时,为了提高用户体验,我们可以给关键词标注高亮和分页返回结果。

5.1 给关键词标注高亮。

 1     public  static String displayHtmlHighlight(Query query, String fieldName, String fieldContent) throws IOException, InvalidTokenOffsetsException
 2     {
 3          MyIkAnalyzer analyzer=new MyIkAnalyzer();
 4          //设置高亮标签,可以自定义
 5          SimpleHTMLFormatter formatter = new SimpleHTMLFormatter("<font color=‘#ff0000‘>", "</font>");
 6          /**创建QueryScorer*/
 7          //评分
 8          QueryScorer scorer=new QueryScorer(query);
 9          /**创建Fragmenter*/
10          Fragmenter fragmenter = new SimpleSpanFragmenter(scorer);
11          //高亮分析器
12          Highlighter highlight=new Highlighter(formatter,scorer);
13          highlight.setTextFragmenter(fragmenter);
14          //fieldname是域名,如"title",fieldContent是d.get("title");
15          String str=highlight.getBestFragment(analyzer, fieldName, fieldContent);
16          if (str==null) return fieldContent;
17          return str;
18      }

displayHtmlHighlight

该函数有三个参数:

  • Query query是第4步产生的查询对象。
  • String fieldName是要标注内容的域名,比如“title”
  • String fieldContent是要标注的具体内容,比如某一个“title”的具体内容。

该函数实现了两个基本功能:

  • 如果要标注内容fieldContent为空,返回空串。
  • 不为空时,对fieldContent进行自定义的html标签标注。

1 SimpleHTMLFormatter formatter = new SimpleHTMLFormatter("<font color=‘#ff0000‘>", "</font>");  

formatter

这里可以进行个性化定制。关于HighLighter的具体用法大家可以参考我的另一篇博客【lucene系列学习二】Lucene实现高亮显示关键词

5.2 分页展示结果。

这里介绍一种简单的分页方法:

1 int start=(pageIndex-1)*pageSize;
2 int end=pageIndex*pageSize;
3  Document d=null;
4  int cnt=0;
5  for(int i=start;i<end&&i<sds.length;i++)
6 {
7         d = searcher.doc(sds[i].doc);
8     //输出d
9 }     

分页

其中pageIndex和pageSize可以是前端传的参数。

以上五个步骤就可以基本实现Lucene的检索、关键词高亮和分页返回结果了,是不是很简单呢?

下节我们会介绍Lucene的高级检索方式~~

时间: 2025-01-18 13:41:09

3.6 Lucene基本检索+关键词高亮+分页的相关文章

和我一起打造个简单搜索之SpringDataElasticSearch关键词高亮

前面几篇文章详细讲解了 ElasticSearch 的搭建以及使用 SpringDataElasticSearch 来完成搜索查询,但是搜索一般都会有搜索关键字高亮的功能,今天我们把它给加上. 系列文章 一.和我一起打造个简单搜索之ElasticSearch集群搭建 二.和我一起打造个简单搜索之ElasticSearch入门 三.和我一起打造个简单搜索之IK分词以及拼音分词 四.和我一起打造个简单搜索之Logstash实时同步建立索引 五.和我一起打造个简单搜索之SpringDataElasti

如何通过js使搜索关键词高亮

给你推荐通过jquery来实现高亮关键词.jquery.textSearch-1.0.js代码: (function($){ $.fn.textSearch =function(str,options){ var defaults ={ divFlag:true, divStr:" ", markClass:"", markColor:"red", nullReport:true, callback:function(){ returnfalse

微信小程序--搜索关键词高亮

代码地址如下:http://www.demodashi.com/demo/14249.html 一.前期准备工作 软件环境:微信开发者工具 官方下载地址:https://mp.weixin.qq.com/debug/wxadoc/dev/devtools/download.html 1.基本需求. 实现搜索关键词高亮 2.案例目录结构 二.程序实现具体步骤 1.index.wxml代码 <!--index.wxml--> <view class="container"

2 Match、Filter、排序、分页、全文检索、短语匹配、关键词高亮

查索引内所有文档记录 GET  /beauties/my/_search GET  /beauties/my/_search { "query":{ "match_all": {} } } 匹配.排序 GET  /beauties/my/_search { "query": { "match": { "Name": "Ruru" } }, "sort": [ {&qu

一个Solr搜索实例,增删改查+高亮+分页

今天个人coding的模块测试,所以闲暇之余继续研究solr,然后顺带写了一个实例,随便搞的,solr真心不熟,期待认识热爱搜索的朋友,共同进步. 1.配置schema.xml文件[solr\collection1\conf\目录下] 因为schema默认定义了一些Field,我们这里选取[id,title,description, author]这几个属性,将id主键type配置为string,其它几个type配置为自定义的ik分词器 <field name="id" type

[原创]java WEB学习笔记90:Hibernate学习之路-- -HQL检索方式,分页查询,命名查询语句,投影查询,报表查询

本博客的目的:①总结自己的学习过程,相当于学习笔记 ②将自己的经验分享给大家,相互学习,互相交流,不可商用 内容难免出现问题,欢迎指正,交流,探讨,可以留言,也可以通过以下方式联系. 本人互联网技术爱好者,互联网技术发烧友 微博:伊直都在0221 QQ:951226918 -----------------------------------------------------------------------------------------------------------------

Qt关键词高亮方法小结

高亮关键词的需求不一样,可能采用的比较适合的方法也不一样,以下对常见方法作小结. 1 QSyntaxHighlighter QSyntaxHighlighter用于高亮QTextDocument中的text,要求继承QSyntaxHighlighter并实现highlightBlock virtual void highlightBlock(const QString &text) = 0; 下面给出示例代码: //.h #ifndef HIGHLIGHTER_H #define HIGHLIG

关键词高亮

从网上找了个正则 <html> <head> <style>body {font:14px/18px Consolas;}</style> </head> <body> <script id="code"> //读入当前代码 var code="'xX' 12 function if Object null true /* ab\nc */ "; //修正换行的浏览器差异,去掉头尾的

页面的关键词高亮

function keyLight(id, key, bgColor) { var oDiv = document.getElementById(id), sText = oDiv.innerHTML, bgColor = bgColor || "orange", sKey = "<span style='color: " + bgColor + ";'>" + key + "</span>", num