Lucene入门

248 阅读5分钟

什么是Lucene

​ Lucene是apache软件基金会4 jakarta项目组的一个子项目,是一个开放源代码的全文检索引擎工具包,但它不是一个完整的全文检索引擎,而是一个全文检索引擎的架构,提供了完整的查询引擎和索引引擎,部分文本分析引擎。Lucene是一个高性能、可伸缩的信息搜索(IR)库。它可以为你的应用程序添加索引和搜索能力。

lucene特点

lucene优点

  • 索引文件格式独立于应用平台。Lucene定义了一套以8位字节为基础的索引文件格式,使得兼容系统或者不同平台的应用能够共享建立的索引文件。
  • 在传统全文检索引擎的倒排索引的基础上,实现了分块索引,能够针对新的文件建立小文件索引,提升索引速度。然后通过与原有索引的合并,达到优化的目的。
  • 优秀的面向对象的系统架构,使得对于Lucene扩展的学习难度降低,方便扩充新功能。
  • 设计了独立于语言和文件格式的文本分析接口,索引器通过接受Token流完成索引文件的创立,用户扩展新的语言和文件格式,只需要实现文本分析的接口。
  • 已经默认实现了一套强大的查询引擎,用户无需自己编写代码即可使系统可获得强大的查询能力,Lucene的查询实现中默认实现了布尔操作、模糊查询(Fuzzy Search[11])、分组查询等等。

lucene缺点

  1. lucene底层是使用倒排索引算法,索引文件会额外的占用磁盘空间

lucene文件结构

四种基本数据类型

  • Index:索引,由很多的 Document 组成。
  • Document:由很多的 Field 组成,是 Index 和 Search 的最小单位,是Field的一个承载体。
  • Field:由很多的 Term 组成,包括 Field Name 和 Field Value。是否分词、是否索引、是否存储
  • Term:由很多的字节组成。一般将 Text 类型的 Field Value 分词之后的每个最小单元叫做 Term。

常见的Field类型

Field类数据类型是否分词是否索引是否存储说明
StringField(FieldName,FieldValue,Store)字符串NYY/N这种类型的不分词,只索引;存储与否取决于Store参数;可以用来存储订单号、 申身份证号码等数据
FloatPointFloatYYN用来创建Float类型的Field,进行分词和索引,不存储;可以用来储存价格等数据
DoublePointDoubleYYN用来创建Double类型的Field,进行分词和索引,不存储;可以用来储存价格等数据
LongPointLongYYN用来创建Long类型的Field,进行分词和索引,不存储;可以用来储存价格等数据
IntPointIntegerYYN用来创建Integer类型的Field,进行分词和索引,不存储;可以用来储存价格等数据
StoreField(FieldName,FieldValue)支持多种类型NNY用于构建不同的Field,不分词,不索引,但是会存储
TextField(FieldName,FieldValue,Store.NO)字符串或者流YNY/N
NumericDocValuesField(FieldName,FieldValue)数值---配合其他域排序使用

Lucene使用

分词器Analyzer

  • 在创建索引的时候需要用到分词器,在使用字符串搜索的时候也会用到分词器,并且这两个地方要使用同一个分词器,否则可能会搜索不出来结果。
  • 分词器(Analyzer)的作用是把一段文本中的词按规则取出所包含的所有词,对应的是Analyzer类,这是一个抽象类(public abstract class org.apache.lucene.analysis.Analyzer),切分词的具体规则是由子类实现的,所以对于不同的语言规则,要有不同的分词器。

分词器主要分为中文分词和英文分词;目前官方的分词器针对英文分词比较友好,适用于中文的分词器一般使用第三方的分词,如IKAnalyzer、paoding等常用的是IKAnalyzer

两个核心组件,Tokenizer以及TokenFilter。两者的区别在于,前者在字符级别处理流,而后者则在词语级别处理流。Tokenizer是Analyzer的第一步,其构造函数接收一个Reader作为参数,而TokenFilter则是一个类似的拦截器,其参数可以是TokenStream、Tokenizer;Lucene支持使用自定义的分词器

创建索引时使用的分词器需要和查询时使用的分词器一样

Lucene查询

基于Query对象构建查询条件,使用IndexSearcher执行查询

Query描述
MatchAllDocQuery无条件的查询所有对象,等价于select * from tableName
TermQuery词条精确匹配,select * from tableName where name = "XX";
WildcardQuery通配符匹配查询,类似mysql的like查询select * from tableName where name like "XX";
FuzzyQuery相似度距离(容纳错误的字符数量),值:0-2,默认值2;如果是0,则和词条精确匹配一样的效果,单词字符串数量相同
TermRangeQuery字符范围查询
QueryParser分词查询,先对查询条件进行分词,再查询
BooleanQuery组合条件查询,可能需要多个规则配合使用。该对象将这些规则组合到一起;Occur表示该条件的规则,如果查询条件都是MUST_NOT的时候,则查询不出任何数据(Lucene底层对搜索引擎的优化)

Lucene对数据的更新

Lucene底层对数据的更新时先删除满足条件的原始数据,然后在末尾重新添加数据

Lucene优化

分词器选择

针对中文的分词最好使用IK分词器,IK分词器中的停用词典和拓展词典文件注意使用;停用词典和拓展词典每一个词语之间需要换行处理

索引存储位置

使用MMapDirectory替代FSDirectory;MMapDirectory,是内存映射;在索引写入的时候,会写到硬盘上,在读取的时候,第一次会在硬盘上读取,后面会直接从内存中读取

搜索api选择

  1. 尽量使用TermQuery替代QueryParser

  2. 尽量避免大范围的日期查询