3.6 Lucene基本检索+关键词高亮+分页
3.2节我们已经运行了一个Lucene实现检索的小程序,这一节我们将以这个小程序为例,讲一下Lucene检索的基本步骤,同时介绍关键词高亮显示和分页返回结果这两个有用的技巧。
一、Lucene检索的基本步骤
import java.nio.file.Paths;
import java.io.*; import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.index.DirectoryReader;
import org.apache.lucene.queryparser.classic.QueryParser;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.ScoreDoc;
import org.apache.lucene.search.TopDocs;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.FSDirectory;
import org.apache.lucene.util.Version; /**
* @author csl
* @description:
* 依赖jar:Lucene-core,lucene-analyzers-common,lucene-queryparser
* 作用:使用索引搜索文件
*/
public class Searcher {
public static Version luceneVersion = Version.LATEST;
/**
* 查询内容
*/
public static String indexSearch(String keywords){
String res = "";
DirectoryReader reader = null;
try{
// 1、创建Directory
Directory directory = FSDirectory.open(Paths.get("index"));//在硬盘上生成Directory
// 2、创建IndexReader
reader = DirectoryReader.open(directory);
// 3、根据IndexReader创建IndexSearcher
IndexSearcher searcher = new IndexSearcher(reader);
// 4、创建搜索的query
// 创建parse用来确定搜索的内容,第二个参数表示搜索的域
QueryParser parser = new QueryParser("content",new StandardAnalyzer());//content表示搜索的域或者说字段
Query query = parser.parse(keywords);//被搜索的内容
// 5、根据Searcher返回TopDocs
TopDocs tds = searcher.search(query, 20);//查询20条记录
// 6、根据TopDocs获取ScoreDoc
ScoreDoc[] sds = tds.scoreDocs;
// 7、根据Searcher和ScoreDoc获取搜索到的document对象
int cou=0;
for(ScoreDoc sd:sds){
cou++;
Document d = searcher.doc(sd.doc);
// 8、根据document对象获取查询的字段值
/** 查询结果中content为空,是因为索引中没有存储content的内容,需要根据索引path和name从原文件中获取content**/
res+=cou+". "+d.get("path")+" "+d.get("name")+" "+d.get("content")+"\n";
} }catch(Exception e){
e.printStackTrace();
}finally{
//9、关闭reader
try {
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return res;
}
public static void main(String[] args) throws IOException
{
System.out.println(indexSearch("你好")); //搜索的内容可以修改
}
}
Searcher
搜索的过程总的来说就是将词典及倒排表信息从索引中读出来,根据用户输入的查询语句合并倒排表,得到结果文档集并对文档进行打分的过程。
总结起来检索有以下以下五个步骤:
1. 打开IndexReader指向索引文件夹。
Directory directory = FSDirectory.open(Paths.get("index"));
IndexReader reader = DirectoryReader.open(directory);
IndexReader
这一步骤将磁盘上的索引信息读入内存。
2. 创建IndexSearcher准备进行搜索。
IndexSearcher searcher = new IndexSearcher(reader);
IndexSearcher
IndexSearcher提供了两个非常重要的函数:
- void setSimilarity(Similarity similarity),用户可以实现自己的Similarity对象,从而影响搜索过程的打分。
- 一系列search函数,是搜索过程的关键,主要负责打分的计算和倒排表的合并。
3. 创建QueryParser解析查询语句生成查询对象。
QueryParser parser = new QueryParser("content",new StandardAnalyzer());//content表示搜索的域或者说字段
Query query = parser.parse(keywords);//被搜索的内容
QueryParser
解析分为两个过程:
- 创建Analyer用来对查询语句进行词法分析和语言处理。
- QueryParser调用parser进行语法分析,形成查询语法树,放到Query中。
4. IndexSearcher调用search对查询语法树Query进行搜索,得到结果集Topdocs。
// 5、根据Searcher返回TopDocs
TopDocs tds = searcher.search(query, 20);//查询20条记录
// 6、根据TopDocs获取ScoreDoc
ScoreDoc[] sds = tds.scoreDocs;
Search
该方法收集文档集合并计算打分。
5. 返回查询结果给用户。
int cou=0;
for(ScoreDoc sd:sds){
cou++;
Document d = searcher.doc(sd.doc);
// 8、根据document对象获取查询的字段值
/** 查询结果中content为空,是因为索引中没有存储content的内容,需要根据索引path和name从原文件中获取content**/
res+=cou+". "+d.get("path")+" "+d.get("name")+" "+d.get("content")+"\n";
}
Document
在返回查询结果给用户时,为了提高用户体验,我们可以给关键词标注高亮和分页返回结果。
5.1 给关键词标注高亮。
public static String displayHtmlHighlight(Query query, String fieldName, String fieldContent) throws IOException, InvalidTokenOffsetsException
{
MyIkAnalyzer analyzer=new MyIkAnalyzer();
//设置高亮标签,可以自定义
SimpleHTMLFormatter formatter = new SimpleHTMLFormatter("<font color='#ff0000'>", "</font>");
/**创建QueryScorer*/
//评分
QueryScorer scorer=new QueryScorer(query);
/**创建Fragmenter*/
Fragmenter fragmenter = new SimpleSpanFragmenter(scorer);
//高亮分析器
Highlighter highlight=new Highlighter(formatter,scorer);
highlight.setTextFragmenter(fragmenter);
//fieldname是域名,如"title",fieldContent是d.get("title");
String str=highlight.getBestFragment(analyzer, fieldName, fieldContent);
if (str==null) return fieldContent;
return str;
}
displayHtmlHighlight
该函数有三个参数:
- Query query是第4步产生的查询对象。
- String fieldName是要标注内容的域名,比如“title”
- String fieldContent是要标注的具体内容,比如某一个“title”的具体内容。
该函数实现了两个基本功能:
- 如果要标注内容fieldContent为空,返回空串。
- 不为空时,对fieldContent进行自定义的html标签标注。
SimpleHTMLFormatter formatter = new SimpleHTMLFormatter("<font color='#ff0000'>", "</font>");
formatter
这里可以进行个性化定制。关于HighLighter的具体用法大家可以参考我的另一篇博客【lucene系列学习二】Lucene实现高亮显示关键词
关于关键词高亮的具体原理可以参考搜索结果的处理和显示《第六篇》
5.2 分页展示结果。
这里介绍一种简单的分页方法:
int start=(pageIndex-1)*pageSize;
int end=pageIndex*pageSize;
Document d=null;
int cnt=0;
for(int i=start;i<end&&i<sds.length;i++)
{
d = searcher.doc(sds[i].doc);
//输出d
}
分页
其中pageIndex和pageSize可以是前端传的参数。
以上五个步骤就可以基本实现Lucene的检索、关键词高亮和分页返回结果了,是不是很简单呢?
下节我们会介绍Lucene的高级检索方式~~
3.6 Lucene基本检索+关键词高亮+分页的更多相关文章
- Lucene 05 - 使用Lucene的Java API实现分页查询
目录 1 Lucene的分页查询 2 代码示例 3 分页查询结果 1 Lucene的分页查询 搜索内容过多时, 需要考虑分页显示, 像这样: 说明: Lucene的分页查询是在内存中实现的. 2 代码 ...
- 和我一起打造个简单搜索之SpringDataElasticSearch关键词高亮
前面几篇文章详细讲解了 ElasticSearch 的搭建以及使用 SpringDataElasticSearch 来完成搜索查询,但是搜索一般都会有搜索关键字高亮的功能,今天我们把它给加上. 系列文 ...
- php-设置关键词高亮的字符串处理函数
/** * 设置关键词高亮的字符串处理函数 * @param [string] $str [要高亮的字符串] * @param array $word_arr [关键词] */function set ...
- jQuery实现页面关键词高亮
示例代码,关键位置做了注释,请查看代码: <html> <head> <title>jQuery实现页面关键词高亮</title> <style ...
- 微信小程序--搜索关键词高亮
代码地址如下:http://www.demodashi.com/demo/14249.html 一.前期准备工作 软件环境:微信开发者工具 官方下载地址:https://mp.weixin.qq.co ...
- lucene查询索引库、分页、过滤、排序、高亮
2.查询索引库 插入测试数据 xx.xx. index. ArticleIndex @Test public void testCreateIndexBatch() throws Exception{ ...
- 2 Match、Filter、排序、分页、全文检索、短语匹配、关键词高亮
查索引内所有文档记录 GET /beauties/my/_search GET /beauties/my/_search { "query":{ & ...
- Django Haystack 全文检索与关键词高亮
Django Haystack 简介 django-haystack 是一个专门提供搜索功能的 django 第三方应用,它支持 Solr.Elasticsearch.Whoosh.Xapian 等多 ...
- 一个Solr搜索实例,增删改查+高亮+分页
今天个人coding的模块测试,所以闲暇之余继续研究solr,然后顺带写了一个实例,随便搞的,solr真心不熟,期待认识热爱搜索的朋友,共同进步. 1.配置schema.xml文件[solr\coll ...
随机推荐
- Percona-Tookit工具包之pt-mext
Preface We are always obliged to analyze many outputs generated by various tools directly ev ...
- 带搜索框的select下拉框
利用select2制作带有搜索功能的select下拉框 1.引入线上css和js <link href="https://cdnjs.cloudflare.com/ajax/libs/ ...
- 使用Windows Live Writer写文章时不要用360清除垃圾
ref:http://www.zhengsiwei.com/write-an-article-to-use-windows-live-writer-dont-use-360-to-remove-rub ...
- Android AppUtil通用类
1.整体分析 1.1.先看一下源码,可以直接Copy. public class AppUtil { /** * 获取当前程序包名 * * @param context 上下文 * @return 程 ...
- 20145202课后题,2.56&9.16
我做的是2.56题,要求我用多组值来测试show_bytes 9.16 主要是对局部性进行了一些分析. 实验楼里面是空的,我电脑上显示不出来,所以我就做了一些书上的习题. 第十章的所有题目都被学长做过 ...
- saltstack plug in
目录 可插拔的子系统 灵活性 虚拟模块 salt的核心架构提供了一种高速的交流总线,在核心架构的上层,salt暴露出来的特征是:松散耦合,可插拔的子系统. 可插拔的子系统 salt包含20中插件系统, ...
- 挂个AC自动机
struct ACM{ ],f[N],cnt[N]; int sz,rt; int ins(char *s){ int n=strlen(s),u=rt; ;i<n;i++){ int c=s[ ...
- istringstream输入数据到数组
istringstream iss(line); ; while (!(iss >> dat[n]).fail()) n++;
- Jenkins拾遗--第一篇(安装Jenkins)
起因 近期由于工作需要做起了起了jenkins的维护.不做不知道,一搞发现里边全是小坑.两个月弄了一身泥.曾经小瞧了它,但是发现其实要弄好它不是那么容易的.有句知名的话"没有总结就没有提高. ...
- python学习笔记十三:Flask demo
一.Flask简介 Flask 是一个 Python 实现的 Web 开发微框架.官网:http://flask.pocoo.org/ 二.Demo 1.代码结构 . ├── blog.py ├── ...