本demo 简单模拟实现一个图书搜索功能
- 模拟向数据库添加数据的时候,添加书籍索引
- 提供搜索接口,支持按照书名作者,内容进行搜索
- 按默认规则排序返回搜索结果。
Lucene提供了一个优秀的全文索引嘚解决方案本文主要关注Lucene的实际应用,所以各位如果想更多更细致的了解Lucene的发展历程和原理可以自行百度或谷歌
我本地的项目结構如图所示:
3.通过使用lucene生成全文索引
在进行具体操作之前,各位需要明白在Lucene的概念中每个即将被索引的文档都叫做Document,每个Document对象都包含┅些不同类型 的Field,可以将Document理解成数据库中的一张表而每张表又包含标题、发表时间、文章内容等字段,这每一个字段就相当于一个Field将 ┅个文档转化成Document对象以后就可以使用IndexWriter的实例将这个Document对象加入到索引文件中,在这之中会将 Document对象进行分词的操作借助的是Lucene的Analyzer的不同实例,烸种实例都相当于一种具体的分词策略
4.使用Lucene通过已生成的索引文件根据关键词检索文档
进行完上述操作以后,各位会发现你所指定的索引苼成目录中会多出一些.cfe/.cfs/.si文件这些文件就是Lucene生成的索引文件。下面为大家介绍如何利用这些索引文件对文档进行全文检索
高亮功能嘚基本原理就是将所查询到的关键词,用指定的HTML标签进行替换如将原有的“message”字符,替换为 “<font color=‘red’>message</font>”这样在文本显示是便可以将message进行紅色高亮显示。此操作
各位可以自行新建一些文件夹和文档作为测试数据
本demo 简单模拟实现一个图书搜索功能
如果索引操作是由多线程完成的,则新编入索引的文档不能被该searcher看到
若要看到这些新文档,则必须打开一个噺的reader
在程序后台,search()方法会快速完成大量工作
它会访问所有候选的搜索匹配文档,并只返回符合每个查询约束条件的结果
最后,它会收集最靠前的几个搜索结果并返回给调用程序
每次用户换页浏览时,都要重新进行查询操作
说明: 重新查询通常是更好的解决方案它可以不用存储每个用户的当前浏览状態,
但对Web应用来说开销太大尤其是有巨大用户群的应用程序。
不过Lucene的快速处理能力正好可以弥补这个缺陷。
此外现在的操作系统的I/O緩存机制,使得重新查询操作通常会很快完成
不需要过早使用缓存或存储来对页面导航进行优化,因为直接按页搜索的方式,可能已經满足你的需求了
近实时搜索,可以对新创建但还未完成提交的段进行搜索
对于索引中任何未发生变更的部分来说,新的reader会共享这些蔀分中打开的文件并能缓存先前的reader。
这种方式速度很快翻转时间不到一秒。
每当搜索到匹配文档时该文档都会被赋予一定的分值,鼡以反映匹配程度
该分值会计算文档与查询语句之间的相似程度,更高的分值反映了更强的相似程度和匹配程度
Lucene相似度评分公式,用來衡量查询语句和对应匹配文档之间的相似程度
计算方式为: 查询语句q中每个项t与文档d的匹配分值之和。
评分归一化处理: 用该查询对應的评分除以最大评分评分越大,说明文档和查询之间的匹配越好
Explanation对象内部包含了所有关于评分计算中各个因子的信息细节。
通过Explanation对潒可以方便看到评分计算的内部运作,但它需要的开销是和做查询操作一样的
索引中的各个Term对象会按照字典编排顺序进行排序,
搜索時包含或不包含起始项和终止项如果某个项为空,则意昧着没有边界
PrefixQuery 用来搜索包含以指定字符串开头的项的文档。
BooleanQuery对其中包含的查询孓句是有数量限制的默认情况下允许包含1024个查询子句。
这个限制主要是为了防止对应用程序的性能造成影响
在匹配的情况下,两个项嘚位置之间所允许的最大间隔距离称为slop
这时的距离是指,项若要按顺序组成给定的短语所需要移动位置的次数
如果slop为0,则表示要求查詢结果必须和输入的短语完全匹配
无论短语中有多少个项,slop因子都规定了按顺序移动项位置的总次数的最大值
短语查询是根据短语匹配所需要的编辑距离来进行评分的。
项之间的距离越小具有的权重就越大。
评分与距离成反比关系距离越大的匹配,其评分就越低
通配符查询可以让我们使用不完整的、缺少某些字项的项进行查询,仍然可以查到相关的匹配结果
Lucene使用两个标准的通配符: *代表0个或者哆个字母,?代表0个或者1个字母
注意: 当使用通配符查询时,可能会降低系统性能较长的前缀可以减少用于查找匹配搜枚举的个数。
如果是以通配符打头则会强制枚举所有索引中的项,以便用于搜索匹配
Levenshtein距离算法用来决定索引文件中的项与指定目标项的相似程序。
这種算法又称为编辑距离算法:它是两个字符串之间相似度的一个度量方法
编辑距离是用来计算从一个字符串到另一个字符串所需的最少插入、删除和替换的字母个数。
默认情况下该类对匹配的文档分配了一个固定的评分,该文档具体的查询加权默认值为1.0
如果将该查询莋为顶层查询,则除了使用默认的相关性排序之外最好通过域来排序。
当查询表达式被QueryParser对象解析后会产生什么变化呢?
很重要的一点QueryParser使用的分析器与索引期间使用的分析器最好保持一致。
针对文本或日期的范围查询所采用的是括号形式,并且只需要在查询范围两端嘚项之间用TO进行连接即可
TO必须都是大写字母。
括号的类型:中括号表示包含在内大括号表示排除在外。
即: 搜索范围的起点和终点偠么都是包含在内,要么都是排除在外
在使用QueryParser类进行通配符查询时,默认情况是不支持项开端包含通配符的
若要改变这个默认限制,可以调用 setAllowLeadingWildcard方法但这个调用会牺牲掉一部分的程序性能。
注意这些布尔操作符必须铨部使用大写形式,列出的项之间如果没有指定布尔操作符,则默认使用OR
查询语句中用双引号括起来的项,可以用来创建一个 PhraseQuery
引号の间的文本将被进行分析,作为分析结果PhraseQuery可能不会跟原始短语一样精确。
波浪号(~)会针对正在处理的项来创建模糊的查询
注意,波浪号還可以用于指定松散短语查询
双引号表示短语查询,它并不能用于模糊查询
可以选择性地指定一个浮点数,用来表示所需的最小相似程度
同样的性能表明,使用通配符WildcardQuery和使用模糊查询是一致的
它们还可以通过自定义方式禁止运行。
同样QueryParser使用分组后的文本类型的查詢表达式来支持同样的功能。
使用小括号来形成子查询以建立高组的BooleanQuery。
默认的域名是在创建QueryParser时提供的但查询语句并不公限制在搜索这個默认的域。
分组而成的查询子句可以使用field(a b c)指定域。空格表示OR
QueryParser 可以快速有效地创建强大的查询,但它并不能适合所囿的场合
如果 QueryParser 不能满足你的功能,你可以继承它并进行定制化
当然,可以通过将QueryParser解析后的查询和调用API建立的查询
联合起来作为BooleanQuery中的查询子句,从而获得一个折中效果