导图社区 Lucene部分
这是一篇关于Lucene部分的思维导图,主要内容有一、Lucene的基础二、索引建立三、搜索功能四、分词五、高级搜索。
编辑于2022-07-16 10:54:25Lucene部分
一、Lucene的基础
1、Lucene的下载
2、Lucene的使用
在全文索引工具中,都是由这样的三部分组成 1、索引部分(I am a boy) 2、分词部分 3、搜索部分
3、基本实例
4、系统架构

5、索引过程的核心类
5.1、IndexWriter
5.2、Directory
5.3、Analyzer
5.4、Document
5.5、Field
6、搜索过程的核心类
6.1、IndexSearcher
6.2、Term
6.3、Query
6.4、TermQuery
6.5、TopDocs
6.6、SocreDoc
二、索引建立
1、基本概念
2、索引过程

3、索引建立步骤
3.1、创建Directory

3.2、创建Writer

3.3、创建文档并且添加索引
文档和域的概念很重要 文档相当于表中的每一条记录,域相当于表中每一个字段 
3.4、查询索引的基本信息
使用IndexReader进行查询 
3.5、删除和更新索引
1、删除   2、恢复删除  3、强制删除  4、优化和合并索引  5、更新索引 
4、域选项
4.1、域索引选项
使用Field.Index.*来进行操作 Index.ANALYZED:进行分词和索引,适用于标题、内容等 Index.NOT_ANALYZED:进行索引,但是不进行分词,如果身份证号,姓名,ID等,适用于精确搜索 Index.ANALYZED_NOT_NORMS:进行分词但是不存储norms信息,这个norms中包括了创建索引的时间和权值等信息 Index.NOT_ANALYZED_NOT_NORMS:即不进行分词也不存储norms信息 Index.NO:不进行索引
4.2、域存储选项
Field.Store.* YES:将会存储域值,原始字符串的值会保存在索引,以此可以进行相应的恢复操作,对于主键,标题可以是这种方式存储 NO:不会存储域值,通常与Index.ANAYLIZED合起来使用,索引一些如文章正文等不需要恢复的文档
4.3、最佳实践
NOT_ANALYZED_NOT_NORMS YES 标识符(主键、文件名),电话号码,身份证号,姓名,日期 ANAYLZED YES 文档标题和摘要 ANAYLZED NO 文档正文 NO YES 文档类型,数据库主键(不进行索引) NOT_ANALYZED NO 隐藏关键字
5、其他知识
5.1、对数字和日期进行索引
1、对数字进行索引可以使用分词器进行不同的索引 ·WhitespaceAnalyzer和StandardAnalyzer会索引数字 ·SimpleAnalyzer和StopAnalyzer不会索引数字 2、在3.0之后添加了数字域来完成数字和日期的索引
5.2、常用的Directory
FSDDirectory.open会根据当前的运行环境打开一个最合理的基于File的Directory new RAMDirectory会从内存中打开directory,好处是速度快,缺点是无法持久化
5.3、IndexReader和IndexWriter的生命周期
对于IndexReader而言,反复使用Index.open打开会有很大的开销,所以一般在整个程序的生命周期中只会打开一个IndexReader,通过这个IndexReader来创建不同的IndexSearcher,如果使用单例模式,可能出现的问题有: 1、当使用Writer修改了索引之后不会更新信息,所以需要使用IndexReader.openIfChange方法操作 如果IndexWriter在创建完成之后,没有关闭,需要进行commit操作之后才能提交
三、搜索功能
1、搜索的简单实现(TermQuery)
1.1、创建IndexReader

1.2、创建IndexSearcher

1.3、创建Term和TermQuery

1.4、根据TermQuery获取TopDocs
 tds.totalHits是总记录数,和传入的num没有任何关系
1.5、根据TopDocs获取ScoreDoc

1.6、根据ScoreDoc获取相应文档

2、其他搜索Query
2.1、TermRangeQuery

2.2、NumericRange
查询某个数字的范围 
2.3、PrefixQuery

2.4、WildcardQuery

2.5、BooleanQuery
可以连接多个条件 
2.6、PhraseQuery

2.7、FuzzyQuery

3、Queryparser
Mike 默认域包含mike Mike john Mike OR john 默认域包含mike或者john +mike +address:zhaotong Mike AND address:zhaotong 默认域即使mike并且address是zhaotong id :2 Id域为2 Address:Kunming –desc:she Address:Kunming AND NOT desc:she Address是kunming并且desc不是she (mike OR john) AND address:zhaotong 默认域是mike或者john 并且address是zhaotong Desc: “she like” Desc域是she like desc:”happy girl”~5 查找happy和girl之间距离小于5的文档 J* 默认域是j开头 Johe~ 模糊搜索johe Id:[“1” TO “3”] Id从1到3
3.1、创建QueryParser

3.2、各种匹配方式

4、分页搜索
再查询  searchAfter(3.5之后才出现的) 
四、分词
1、分词器的核心类
1.1、Analyzer
4、SimpleAnalyzer、StopAnalyzer、WhitespaceAnalyzer、StandardAnalyzer
1.2、TokenStream
分词器做好处理之后得到的一个流,这个流中存储了分词的各种信息,可以通过TokenStream有效的获取到分词单元信息 生成的流程  在这个流中所需要存储的数据 
1.3、Tokenizer
主要负责接收字符流Reader,将Reader进行分词操作。有如下一些实现类 
1.4、TokenFilter
将分词的语汇单元,进行各种各样过滤 
2、Attribute

3、自定义分词器
3.1、自定义Stop分词器

3.2、中文分词器
Paoding:庖丁解牛分词器。已经没有更新了 mmseg:使用搜狗的词库() 1、导入包(有两个包:1、带dic,2、不带dic) 如果使用不带dic的,得自己指定词库位置  2、创建的时候使用MMSegAnalyzer分词器 
3.3、简单实现同义词索引
五、高级搜索
1、搜索排序

1.1、根据分值排序
1.2、根据索引号排序
1.3、根据不同的域进行排序
1.4、倒排序
2、搜索过滤
2.1、TermRangeFilter
2.2、NumericRangeFilter
2.3、QueryWrapperFilter
3、自定义评分

3.1、创建一个类继承于CustomScoreQuery

3.2、覆盖getCustomScoreProvider方法

3.3、创建CustomScoreProvider类

3.4、覆盖customScore方法

3.5、根据field进行评分
 
4、自定义QueryParser
原因: 1、对于某些QueryParser(FuzzyQuery,WildcardQuery)在查询时会使得性能降低,所以考虑将这些查询取消 2、在具体的查询时,很有可能有这样一种需求:需要获取的是一个数字的范围查询。所以必须扩展原有的QueryParser才能进行查询 实现思路:覆盖QueryParser类,并且重载相应方法
4.1、限制性能低的QueryParser

4.2、扩展居于数字和日期的查询

5、自定义过滤器
5.1、定义一个Filter继承Filter类

5.2、覆盖getDocIdSet方法

5.3、设置DocIdSet

六、Lucene的扩展
1、Luke
luke是一个查询索引的工具,使用时必须注意:版本要与lucene的版本完全一致,否则可能打不开索引信息 java -jar luke-xx-xx.jar可以打开索引 选择索引说存储的目录,就可以使用luke查询和操作相应的索引信息,并且可以在search中根据QueryParser来查询相应的信息
2、Tika
Tika是2008年才产生的一个apache的项目,主要用于打开各种不同的文档,1.0
3、高亮显示
1、搜索的关键字高亮(我们正则学习数据结构) 2、拆分内容
3.1、Fragmenter
3.2、QueryScorer
3.3、Encoder
3.4、Formatter
solr
全文搜索服务器 1、下载solr-->Lucene3.5.0(solr3.5.0) SolrJ solr wiki
1、让solr和tomcat整合
1、将solr中的example中的solr拷贝到要作为服务器的位置 2、将相应的solr的web程序也拷贝出来 3、修改solr-->home文件夹中的solrconfig.xml设置data的路径  4、设置相应的tomcat的context  5、为context设置相应的环境变量,说明solr的主目录的地址  6、取消VelocityResponseWriter这种输出格式  7、加入中文分词 7.1、将中文分词的包拷贝到server的lib中 7.2、将中文分词添加到FieldType中 
2、solrJ的使用
1、导入  2、创建SolrServer  3、添加文档 
3、solr添加文档
3.1、直接添加文档

3.2、基于java bean完成文档添加

4、solr的查询
1、基于结果集的查询  2、基于bean的查询 
5、高亮查询

七、Lucene项目运用
1、需求
1.1、索引目标
1、留言的内容 2、留言的标题 3、留言的附件
1.2、索引对象
Index  Field 
1.3、搜索的业务需求
是否进行实时搜索 实时搜索(近实时搜索) 完全的实时搜索:只要数据库一变动,马上要更新索引,writer.commit来操作 近实时搜索:当用户修改了信息之后,先把索引保存到内存中,然后在一个统一的时间对内存中的所有的索引进行提交操作。reopen,NRTManager(near-real-time) SearcherManager IndexReader.open