Lucene搜索核心代码TermInfosReader

摘要:
TermInfosReader类是Lucene搜索的核心代码。所有搜索最终都属于术语查询。TermInfosReader定义了支持的基本术语查询功能。get方法用于查询指定的现有术语。如果该术语不存在,此方法将返回一个空的逻辑描述:当系统初始化时,tii文件中的所有数据都将加载到内存中。具体来说,代码TermInfosReader中的indexTerms和indexInfos以及indexPointers变量。indexTerms将所有单词元数据存储在中。tii文件和indexInfos存储单词元素的附加信息,例如,frq文件和prox文件中相应数据的位置,indexPointers存储每个文件中索引单词的原始位置。中的tii文件。tis文件。


TermInfosReader类是Lucene搜索的核心代码,所有的搜索最终都是落到通过term查询,TermInfosReader里定义了支持的基础的term查询功能。

前置知识:

词元字典文件(tis):

文件描述:

文件中的term按照从小到大排序,排序规则:先按照属性名排,如果属性名相同,再按照词元内容排,简单的字符比较。tis文件中存储的词元列表按照IndexInterval分成多个块,后面在查询逻辑里叙述通过块如何优化搜索。

文件结构:

TermInfos --> <TermInfo>TermCount
TermInfo --> <Term, DocFreq, FreqDelta, ProxDelta, SkipDelta>

词元索引文件(tii):

文件描述:

tii文件是tis文件的索引文件,按照tis文件中存储的IndexInterval间隔存储tii文件,tii文件中词元内容和tis一样,除了词元外,tii文件中每个词元附加一个IndexDelta数据,存储了该词元在tis文件中的位置,

文件结构:

TermIndices --> <TermInfo, IndexDelta>IndexTermCount
IndexDelta --> VInt   // IndexDelta表示这个索引词元在tis文件中的具体位置,类似指针

核心方法一:

TermInfo get(Term term)


方法描述:

方法传入term,返回TermInfo,通过TermInfo里的freqPointer和proxPointer可以从.frq文件中取包含该词元的文档列表,和从.prx文件中取词元在每个文档中出现的位置。get方法是用于查询指定存在的term,如果term不存在这个方法返回一个null
逻辑描述:

系统初始化时将tii文件中的所有数据加载到内存中,具体是代码TermInfosReader里的indexTerms和indexInfos还有indexPointers变量中,indexTerms中存储.tii文件中所有的词元数据,indexInfos存储词元附加信息,比如词元在frq文件和prox文件中的相应数据的位置,indexPointers存储每个.tii文件中索引词元在.tis文件中的原始位置。这几个变量都是数组,按照下标一一对应。
词元都是从小到大排好顺序的,所以要搜索入参term在tis文件中的位置,就要从前往后一个一个遍历。

优化点1:

通过上面已经加载到内存中的tii文件数据可以优化这个查找过程,具体过程如下:
先通过参数term到indexTerms变量中找到一个比自己小而且是最接近的索引词元。在1.4里实现是通过二分查找
然后通过indexTerms、indexInfos、indexPointers这三个变量在下标上的对应关系找到这个最接近且比参数小的索引词元在tis文件中的原始位置,这个数据在indexInfos里有记录。
然后上面的从前往后一个一个遍历可以优化为从上面得到的索引词元开始往后遍历。

优化点2:

  这里还有一个优化点,对于顺序查找且在同一个块内的词元时,其实不需要去索引词元列表里找下标,然后通过下标往后遍历,这时候可以直接通过第一次查询的词元(遍历的当前词元)的位置往后遍历。通过tii文件找也是为了找到一个和当前查询词元最接近的索引词元,现在这种场景下第一次查询的词元是最接近的,所以不需要在使用索引词元查找。

核心方法2:

SegmentTermEnum terms(Term term)

方法描述:

get方法查询指定的词元,terms方法查询匹配的多个词元,用于范围搜索场景,比如前缀查询、模糊查询等。terms方法是基于get方法来实现的,get方法还有个副作用,在执行get方法时会移动当前遍历的指针,如果查询到某个词元,则指针指向该词元,如果没有查询到词元,则把指针定位到与查询词元最近的一个比查询词元大的词元位置。

逻辑描述:

terms方法正是通过这个副作用来工作的,terms的代码很简单:

get(term);
return (SegmentTermEnum)getEnum().clone();

先通过get定位到最小的词元位置,然后返回以命中的最小词元为头的词元链表,调用方可以通过这个链表获取到所有相似的词元以及包含每个词元的文档列表。

免责声明:文章转载自《Lucene搜索核心代码TermInfosReader》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇遍历倒排索引核心类:SegmentTermDocs/SegmentTermPositionsLucene BooleanQuery相关算法下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

关于索引的使用

一般情况下,sql默认的索引是聚集索引,但是这并不是最佳的。合理的索引设计还是要建立在对各种查询的分析和预测的基础上。 一:有大量重复且经常范围查询的(如时间,)order by ,group by查询的。最好使用聚集索引。为什么呢。因为聚集索引就像是新华字典里面的按拼音排序。是整张表的排序方式,那么上面的条件是不是就可以使用这种方式就可以很快的找到数据?呵...

PostgreSQL学习手册 性能提升技巧

http://www.cnblogs.com/mchina/archive/2012/08/11/2537393.html 一、使用EXPLAIN:PostgreSQL为每个查询都生成一个查询规划,因为选择正确的查询路径对性能的影响是极为关键的。PostgreSQL本身已经包含了一个规划器用于寻找最优规划,我们可以通过使用EXPLAIN命令来查看规划器为每个...

mysql视图

mysql视图机制 什么是视图 视图是一张虚拟的表,为什么是虚拟呢?因为视图与数据库中存在的表不太一样,前面我们创建的4张表都是包含数据的, 如用户信息,订单信息等,而视图则是不包含数据的,下面通过一个例子来演示视图,下面的sql是查询王五的所有 订单情况,需要关联到orders表,orderd etail表 tiems表 user表 mysql> s...

6.2Python数据处理篇之pandas学习系列(二)Series数据类型

目录 目录 (一)Series的组成 (二)Series的创建 1.从标量中创建Series数据 2.从列表中创建Series数据 3.从字典中创建Series数据 (1)直接使用字典(不添加index) (2)添加index 4.从ndarry中创建Series数据 5.从其他函数中创建Series数据 (三)Series的操作 1.S...

聚集索引,非聚集索引,覆盖索引原理

「数据库」和「数据库索引」这两个东西是在服务器端开发领域应用最为广泛的两个概念,熟练使用数据库和数据库索引是开发人员在行业内生存的必备技能 使用索引很简单,只要能写创建表的语句,就肯定能写创建索引的语句,要知道这个世界上是不存在不会创建表的服务器端程序员的。然而, 会使用索引是一回事, 而深入理解索引原理又能恰到好处使用索引又是另一回事,这完全是两个天差地别...

设计模式系列之迭代器模式(Iterator Pattern)——遍历聚合对象中的元素

说明:设计模式系列文章是读刘伟所著《设计模式的艺术之道(软件开发人员内功修炼之道)》一书的阅读笔记。个人感觉这本书讲的不错,有兴趣推荐读一读。详细内容也可以看看此书作者的博客https://blog.csdn.net/LoveLion/article/details/17517213。 模式概述 模式定义 在软件开发中,经常需要使用聚合对象来存储一系列数据。...