众所周知,“索引”是搜索引擎中最重要的核心技术之一,是“缩小搜索范围,以提高结果定位效率”的技术担当。
按照不同划分标准,索引有多种分类方式,仅常用类型也不止4种之多,而其中最为关键的则是“倒排索引”技术。
本文就是一篇,介绍“倒排索引创建方法”的文章。
一、相关概念及术语
单词—文档矩阵
表达两者包含关系的概念模型;
文档
文本形式的存储对象,包括Word、PDF、html、XML等不同格式的文件,以及短信、微博等内容;
文档集合
若干文档的集合,如海量网页、大量电子邮件等;
文档编号
搜索引擎内部的文档集合中,每个文档所被赋予的区别于其他文档的唯一的内部编号,常用DocID表示;
单词
搜索引擎的索引单位;
单词词典
文档集合中出现过的所有单词构成的字符串集合;记载着某个单词对应的倒排列表在倒排文件中的位置信息;
单词编号
搜索引擎内部的单词词典中,每个单词所被赋予的区别于其他单词的唯一内部编号;
倒排列表
记载“出现过某个单词的所有文档列表”及“文档中单词位置信息”的倒排项的集合;
倒排文件
顺序存储所有单词的倒排列表的物理文件;
倒排索引
由单词词典和倒排文件组成的,实现单词—文档矩阵的一种具体存储形式,是单词到文档映射关系的最佳实现方式(可以根据单词快速获取包含该单词的文档列表)。
比如,针对如下文档集合
建立倒排索引的步骤:
1、用分词系统将文档自动切分成单词序列,每个文档就转换为由单词序列构成的数据流;
2、对每个不同单词赋予唯一的单词编号(ID),并记录每个单词对应的文档频率(文档集合中,包含某个单词的文档数量,占文档总数量的比率)、包含该单词的对应文档编号(DocID)、该单词在各对应文档中的词频(TF)(在某个文档中出现的次数)、该单词出现在某个文档中的位置(POS)等;
3、得到的倒排索引结果如下:
含义解读:以单词“跳槽”为例,其单词编号为4,文档频率为2,代表整个文档集合中有两个文档包含这个单词,对应的倒排列表为{(1;1;<4>),(4;1;<4>)},其含义为在文档1和文档4中出现过这个单词,单词频率都为1,单词“跳槽”出现在两个文档中的位置都是4,即文档中第四个单词是“跳槽”。
二、单词词典 & 倒排列表
单词词典
记载着某个单词对应的倒排列表在倒排文件中的位置信息,支持搜索中基于查询词的倒排列表呈现。
对于包含成千上万个单词的大文档集合来说,需要“基于高效数据结构”的词典构建和查找方式,“哈希加链表”和“树形词典”就是这类数据结构的代表。
A. 哈希加链表词典结构
哈希加链表:由“哈希表”及“冲突链表”组成,其中哈希表是主体。每个哈希表保存一个指针,指向冲突链表;每个冲突链表,由相同哈希值的单词组成;而有相同哈希值的一组单词,被称作一次冲突。
词典建立过程:首先,对解析新文档过程中出现的单词T,利用哈希函数获得哈希值;然后,根据哈希值,读取对应的哈希表中的指针,并根据指针指向找到对应的冲突链表,而对冲突链表中不存在的单词,将其作为首次出现单词做“加入冲突链表”处理。随着文档解析完毕,相应的词典便构建起来。
查询响应过程:与词典建立过程类似,区别在于,对于词典中未包含单词不做添加处理。
B. 树形词典结构
树形词典结构(又叫B树或B+树),由中间节点和最底层叶子节点构成,是一种高效的层级查询结构。
它需要字典项按照大小排序,中间节点指出一定顺序范围的词典项目存储在哪个子树中,根据词典项比较大小进行导航;最底层叶子节点存储单词地址信息,根据地址便可以提取单词字符串。
倒排列表
我们上面讲了,倒排列表是倒排索引项(“某个单词-文档”的一维矩阵)的集合,存储着所有单词,及包含每个单词的相关文档编号、词频、位置等信息。
而在实际搜索引擎中,为了便于压缩,常以文档编号差值(D-Gap)(倒排列表中相邻两个倒排索引项文档编号的差值)取代实际的文档编号,以保证倒排列表中后出现文档编号大于前者。因此,文档编号差值常是大于0的整数,比如,对应原始文档编号 187、196、199,其编号差值可能为 187、9、3。
三、倒排索引创建方法
1、两遍文档遍历法
两遍文档遍历,即为两遍文档扫描,创建过程完全依赖在内存中进行。
第一遍文档遍历
第一遍扫描旨有两个作用:首先,获取全局的统计数据(文档集合包含的文档个数N,文档集合包含的不同单词个数M、每个单词在多少个文档中出现过的信息DF、所有单词DF值相加得到的所需内存大小),据以分配存储空间;其次,建立单词对应倒排列表在内存中的位置信息(根据每个单词的DF值,将存储区划分成不同大小的片段,不同的单词通过指针对应着其所属内存片段的起始和终止位置)。
第一遍扫描之后,便为第二次扫描做好了资源准备工作。
第二遍文档遍历
第二遍文档遍历正式建立每个单词的倒排列表信息,扫描结束的同时,所分配的内存空间也正好被填满。每个单词对应的内存片段,此时已被创建成该单词的倒排列表。
两遍扫描,便可完成索引建立,并将内存的倒排列表和词典信息写入磁盘。
优缺点:完全依赖内存,要求内存空间足够大;从磁盘读取和解析文档耗时较长,速度慢。
2、排序法
一种“在索引建立过程中,始终在内存分配固定大小的空间,用来存放词典信息和索引中间结果,当分配空间被消耗殆尽,把中间结果写入磁盘,并清空内存做新一轮中间索引存储”的方法,是两遍遍历索引的改进。
中间结果内存排序
a.读入文档,赋予唯一的文档ID;
b.解析文档内容,赋予文档中出现的单词以唯一的单词ID(首次出现的单词,赋予ID后做插入处理);
c.为每个单词建立包含“单词ID”、“文档ID”、”单词频率”信息的倒排列表项,并将其追加进中间结果存储区末尾;对所有文档依次做以上处理,直到所有文档被处理完毕。
d.随着存储中间结果的内存被逐渐占满,对三元组中间结果进行排序,将各单词对应的倒排索引项变成有序形式,并将排好序的倒排列表写入磁盘。排序原则:主键是单词ID,即先按单词ID从小到大排序;次键是文档ID, 即相同单词ID下,按文档ID从小到大排序。
e.循环以上处理过程,待所有文档被处理完毕,合并磁盘中每轮产生的中间结果文件。
中间结果文件合并
将存放中间结果的各缓冲区的有序数据,按单词ID顺序合并形成倒排列表写入最终索引,同时清空各缓冲区并进行新一轮三元组读入操作,待所有中间结果文件被读入缓冲区合并完成,最终索引文件便得以生成。
优缺点:只对中间结果做写入磁盘操作,词典信息始终在内存中维护,随着内存被不断占用,后续中间结果可用内存会越来越少。
3、归并法
归并法,是排序法的改进,每次将内存数据写入磁盘时,包括词典在内的中间结果信息也被写入磁盘,以达到清空内存并为后续处理建立定额内存的目的。
子倒排索引
对目前所处理的文档子集单独在内存中建立一整套的倒排索引;
将倒排索引写入临时文件
内存被占满时,按照“词典在前,倒排列表在后”的顺序,将已建立的一整套倒排索引写入临时文件,并清空内存。
合并部分倒排列表
合并每个单词对应的部分倒排列表,形成单词的最终倒排列表;同时,在合并过程中形成最终的词典。