2.1 文档索引概述

在信息检索过程中,文本数据首先要经过加工处理后才能被检索到,而这个加工处理过程就是建立索引文件(通常是倒排索引文件)。一般的信息检索过程是用户通过接口提交查询请求,在索引文件中检索出相关结果,并按相关度排序之后返回给用户。可见,建立文档索引是基础的加工过程。由于检索通常要面向大量用户的查询,因此索引文件的设计要尽量高效,以便由索引项快速定位到相应文档。当前文档索引方法有倒排索引、后缀数组索引、签名文件索引等,其中倒排索引是用得最广的。在Lucene中,采用的就是经典的倒排索引技术。目前成熟的信息检索系统几乎普遍采用这种索引方法。可以说,倒排索引是检索技术的基础。

倒排文件可看作是一种描述了一个词项集合terms元素和一个文档集合docs元素对应关系的数据结构。若记N为文档集合的大小,M为词项集合的大小,docs={d1, d2, …, d N}, ter m s={t 1, t 2, …, t M},则倒排文件可给出tj出现在哪些d i中(或tjd i中出现在哪些位置)的信息。一般地,它从逻辑上看可分为两个部分:一部分用于表示文档的索引项;另一部分则由多个位置表组成,每个位置表和索引中的某个索引项相对应,并记录所有出现过该索引项的文档及其在文档中的具体位置,以便计算出索引项之间的相邻关系。图2.1是一个倒排索引结构示意图,表示在文档d1d2中出现过“应用”这个索引项,而在文档d2d3出现过“技术”索引项。由于d2文档中上述两个索引项是相邻的(分别位于51和52的位置,见图2.1),因此“应用技术”就应该出现在d2文档中。如果要检索“应用技术”一词,则首先在倒排索引中找到包含“应用”一词的候选文档集合,然后从候选文档集合中筛选出在这个检索词后紧跟“技术”的文档(是d2,而非d1d3)。这种方式可以加快检索速度[高凯,2014]

图2.1 倒排文件示意图

Elasticsearch“准实时”索引的关键就是对于新收到的数据,要将其写到新的索引文件里。倒排索引机制会将文本信息切分成称为token的信息单元,再利用这些token构造倒排索引。索引文件一般由一个或多个子索引段segment组成,生成segment的数据则来源于内存中的缓存。除了segment外,索引文件中还有一个commit文件,用来记录索引内所有的segment信息。假设系统检测到当前索引有M个segment,对新接收的进入内存缓冲区中的数据,首先以缺省值1秒的时间间隔,将其刷新到文件系统的缓存中去,这样系统即可准实时检索到这个segment中的信息。Elasticsearch也提供了单独的/_refresh接口,如果需要缩短这个缺省1秒时间间隔,可以通过调用这个接口来实现个性化的操作。同时,将数据定时输出到硬盘,segment数量增加到(M+1)个,并同步更新commit文件。随着时间的推移,上述这个方法的弊端就是可能存在大量零散的segment文件。为此,Elasticsearch会在后台运行相关的任务,定期主动将这些零散的segment数据归并,尽量让索引只保留少量的、较大的segment文件。归并完成后,检索请求将在这些归并后的较大的segment上进行。具体实施中,归并线程是按照一定的策略来挑选segment进行归并的。相关技术细节可参阅文献[饶琛琳,2015]