什么是正向索引、反向索引(倒排索引)?

1.正向索引

正向索引(正排索引):正排表是以文档的ID为关键字,表中记录文档中每一个字的位置信息,查找时扫描表中每一个文档中字的信息直到找出全部包含查询关键字的文档。html

“文档1”的ID > 单词1:出现次数,出现位置列表;单词2:出现次数,出现位置列表;…………。
“文档2”的ID > 此文档出现的关键词列表。
在这里插入图片描述web

正排表结构如图1所示,这种组织方法在创建索引的时候结构比较简单,创建比较方便且易于维护;由于索引是基于文档创建的,如果有新的文档加入,直接为该文档创建一个新的索引块,挂接在原来索引文件的后面。如果有文档删除,则直接找到该文档号文档对应的索引信息,将其直接删除。可是在查询的时候需对全部的文档进行扫描以确保没有遗漏,这样就使得检索时间大大延长,检索效率低下。数据结构

尽管正排表的工做原理很是的简单,可是因为其检索效率过低,除非在特定状况下,不然实用性价值不大。svg

反向索引

反向索引(倒排索引):倒排表以字或词为关键字进行索引,表中关键字所对应的记录表项记录了出现这个字或词的全部文档,一个表项就是一个字表段,它记录该文档的ID和字符在该文档中出现的位置状况。函数

因为每一个字或词对应的文档数量在动态变化,因此倒排表的创建和维护都较为复杂,可是在查询的时候因为能够一次获得查询关键字所对应的全部文档,因此效率高于正排表。在全文检索中,检索的快速响应是一个最为关键的性能,而索引创建因为在后台进行,尽管效率相对低一些,但不会影响整个搜索引擎的效率。性能

倒排索引的结构以下:
“关键词1”:“文档1”的ID,“文档2”的ID,…………。
“关键词2”:带有此关键词的文档ID列表。
在这里插入图片描述搜索引擎

3.倒排索引介绍

3.1.单词——文档矩阵

单词-文档矩阵是表达二者之间所具备的一种包含关系的概念模型,图1展现了其含义。下图的每列表明一个文档,每行表明一个单词,打对勾的位置表明包含关系。
在这里插入图片描述.net

从纵向即文档这个维度来看,每列表明文档包含了哪些单词,好比文档1包含了词汇1和词汇4,而不包含其它单词。从横向即单词这个维度来看,每行表明了哪些文档包含了某个单词。好比对于词汇1来讲,文档1和文档4中出现过单词1,而其它文档不包含词汇1。矩阵中其它的行列也可做此种解读。指针

搜索引擎的索引其实就是实现“单词-文档矩阵”的具体数据结构。能够有不一样的方式来实现上述概念模型,好比“倒排索引”、“签名文件”、“后缀树”等方式。可是各项实验数据代表,“倒排索引”是实现单词到文档映射关系的最佳实现方式,因此本文主要介绍“倒排索引”的技术细节。code

3.2.倒排索引基本概念

  • 文档(Document):通常搜索引擎的处理对象是互联网网页,而文档这个概念要更宽泛些,表明以文本形式存在的存储对象,相比网页来讲,涵盖更多种形式,好比Word,PDF,html,XML等不一样格式的文件均可以称之为文档。再好比一封邮件,一条短信,一条微博也能够称之为文档。在本书后续内容,不少状况下会使用文档来表征文本信息。

  • 文档集合(Document Collection):由若干文档构成的集合称之为文档集合。好比海量的互联网网页或者说大量的电子邮件都是文档集合的具体例子。

  • 文档编号(Document ID):在搜索引擎内部,会将文档集合内每一个文档赋予一个惟一的内部编号,以此编号来做为这个文档的惟一标识,这样方便内部处理,每一个文档的内部编号即称之为“文档编号”,后文有时会用DocID来便捷地表明文档编号。

  • 单词编号(Word ID):与文档编号相似,搜索引擎内部以惟一的编号来表征某个单词,单词编号能够做为某个单词的惟一表征。

  • 倒排索引(Inverted Index):倒排索引是实现“单词-文档矩阵”的一种具体存储形式,经过倒排索引,能够根据单词快速获取包含这个单词的文档列表。倒排索引主要由两个部分组成:“单词词典”和“倒排文件”。

  • 单词词典(Lexicon):搜索引擎的一般索引单位是单词,单词词典是由文档集合中出现过的全部单词构成的字符串集合,单词词典内每条索引项记载单词自己的一些信息以及指向“倒排列表”的指针。

  • 倒排列表(PostingList):倒排列表记载了出现过某个单词的全部文档的文档列表及单词在该文档中出现的位置信息,每条记录称为一个倒排项(Posting)。根据倒排列表,便可获知哪些文档包含某个单词。

  • 倒排文件(Inverted File):全部单词的倒排列表每每顺序地存储在磁盘的某个文件里,这个文件即被称之为倒排文件,倒排文件是存储倒排索引的物理文件。

    关于这些概念之间的关系,经过下图能够比较清晰的看出来。
    在这里插入图片描述

3.3.倒排索引简单实例

倒排索引从逻辑结构和基本思路上来说很是简单。下面咱们经过具体实例来进行说明,使得读者可以对倒排索引有一个宏观而直接的感觉。

假设文档集合包含五个文档,每一个文档内容下图所示,在图中最左端一栏是每一个文档对应的文档编号。咱们的任务就是对这个文档集合创建倒排索引。 
在这里插入图片描述
             文档集合

中文和英文等语言不一样,单词之间没有明确分隔符号,因此首先要用分词系统将文档自动切分红单词序列。这样每一个文档就转换为由单词序列构成的数据流,为了系统后续处理方便,须要对每一个不一样的单词赋予惟一的单词编号,同时记录下哪些文档包含这个单词,在如此处理结束后,咱们能够获得最简单的倒排索引(参考图3-4)。在图4中,“单词ID”一栏记录了每一个单词的单词编号,第二栏是对应的单词,第三栏即每一个单词对应的倒排列表。好比单词“谷歌”,其单词编号为1,倒排列表为{1,2,3,4,5},说明文档集合中每一个文档都包含了这个单词。
              (参考图3-4)图4

之因此说图4所示倒排索引是最简单的,是由于这个索引系统只记载了哪些文档包含某个单词,而事实上,索引系统还能够记录除此以外的更多信息。图5是一个相对复杂些的倒排索引,与图4的基本索引系统比,在单词对应的倒排列表中不只记录了文档编号,还记载了单词频率信息(TF),即这个单词在某个文档中的出现次数,之因此要记录这个信息,是由于词频信息在搜索结果排序时,计算查询和文档类似度是很重要的一个计算因子,因此将其记录在倒排列表中,以方便后续排序时进行分值计算。在图5的例子里,单词“创始人”的单词编号为7,对应的倒排列表内容为:(3:1),其中的3表明文档编号为3的文档包含这个单词,数字1表明词频信息,即这个单词在3号文档中只出现过1次,其它单词对应的倒排列表所表明含义与此相同。     
在这里插入图片描述
              图 5 带有单词频率信息的倒排索引

实用的倒排索引还能够记载更多的信息,图6所示索引系统除了记录文档编号和单词频率信息外,额外记载了两类信息,即每一个单词对应的“文档频率信息”(对应图6的第三栏)以及在倒排列表中记录单词在某个文档出现的位置信息。

在这里插入图片描述
             图6 带有单词频率、文档频率和出现位置信息的倒排索引

“文档频率信息”表明了在文档集合中有多少个文档包含某个单词,之因此要记录这个信息,其缘由与单词频率信息同样,这个信息在搜索结果排序计算中是很是重要的一个因子。而单词在某个文档中出现的位置信息并不是索引系统必定要记录的,在实际的索引系统里能够包含,也能够选择不包含这个信息,之因此如此,由于这个信息对于搜索系统来讲并不是必需的,位置信息只有在支持“短语查询”的时候才可以派上用场。

以单词“拉斯”为例,其单词编号为8,文档频率为2,表明整个文档集合中有两个文档包含这个单词,对应的倒排列表为:{(3;1;<4>),(5;1;<4>)},其含义为在文档3和文档5出现过这个单词,单词频率都为1,单词“拉斯”在两个文档中的出现位置都是4,即文档中第四个单词是“拉斯”。

图6所示倒排索引已是一个很是完备的索引系统,实际搜索系统的索引结构基本如此,区别无非是采起哪些具体的数据结构来实现上述逻辑结构。

有了这个索引系统,搜索引擎能够很方便地响应用户的查询,好比用户输入查询词“Facebook”,搜索系统查找倒排索引,从中能够读出包含这个单词的文档,这些文档就是提供给用户的搜索结果,而利用单词频率信息、文档频率信息便可以对这些候选搜索结果进行排序,计算文档和查询的类似性,按照类似性得分由高到低排序输出,此即为搜索系统的部份内部流程,具体实现方案本书第五章会作详细描述。

3.4. 单词词典

单词词典是倒排索引中很是重要的组成部分,它用来维护文档集合中出现过的全部单词的相关信息,同时用来记载某个单词对应的倒排列表在倒排文件中的位置信息。在支持搜索时,根据用户的查询词,去单词词典里查询,就可以得到相应的倒排列表,并以此做为后续排序的基础。
对于一个规模很大的文档集合来讲,可能包含几十万甚至上百万的不一样单词,可否快速定位某个单词,这直接影响搜索时的响应速度,因此须要高效的数据结构来对单词词典进行构建和查找,经常使用的数据结构包括哈希加链表结构和树形词典结构。

3.4.1 哈希加链表

图7是这种词典结构的示意图。这种词典结构主要由两个部分构成:

主体部分是哈希表,每一个哈希表项保存一个指针,指针指向冲突链表,在冲突链表里,相同哈希值的单词造成链表结构。之因此会有冲突链表,是由于两个不一样单词得到相同的哈希值,若是是这样,在哈希方法里被称作是一次冲突,能够将相同哈希值的单词存储在链表里,以供后续查找。
在这里插入图片描述

在创建索引的过程当中,词典结构也会相应地被构建出来。好比在解析一个新文档的时候,对于某个在文档中出现的单词T,首先利用哈希函数得到其哈希值,以后根据哈希值对应的哈希表项读取其中保存的指针,就找到了对应的冲突链表。若是冲突链表里已经存在这个单词,说明单词在以前解析的文档里已经出现过。若是在冲突链表里没有发现这个单词,说明该单词是首次碰到,则将其加入冲突链表里。经过这种方式,当文档集合内全部文档解析完毕时,相应的词典结构也就创建起来了。

在响应用户查询请求时,其过程与创建词典相似,不一样点在于即便词典里没出现过某个单词,也不会添加到词典内。以图7为例,假设用户输入的查询请求为单词3,对这个单词进行哈希,定位到哈希表内的2号槽,从其保留的指针能够得到冲突链表,依次将单词3和冲突链表内的单词比较,发现单词3在冲突链表内,因而找到这个单词,以后能够读出这个单词对应的倒排列表来进行后续的工做,若是没有找到这个单词,说明文档集合内没有任何文档包含单词,则搜索结果为空。

3.4.2 树形结构

B树(或者B+树)是另一种高效查找结构,图8是一个 B树结构示意图。B树与哈希方式查找不一样,须要字典项可以按照大小排序(数字或者字符序),而哈希方式则无须数据知足此项要求。

B树造成了层级查找结构,中间节点用于指出必定顺序范围的词典项目存储在哪一个子树中,起到根据词典项比较大小进行导航的做用,最底层的叶子节点存储单词的地址信息,根据这个地址就能够提取出单词字符串。

在这里插入图片描述
图8 B树查找结构

3.4 总结

单词ID:记录每一个单词的单词编号;
单词:对应的单词;
文档频率:表明文档集合中有多少个文档包含某个单词
倒排列表:包含单词ID及其余必要信息
DocId:单词出现的文档id
TF:单词在某个文档中出现的次数
POS:单词在文档中出现的位置

以单词“加盟”为例,其单词编号为6,文档频率为3,表明整个文档集合中有三个文档包含这个单词,对应的倒排列表为{(2;1;<4>),(3;1;<7>),(5;1;<5>)},含义是在文档2,3,5出现过这个单词,在每一个文档的出现过1次,单词“加盟”在第一个文档的POS是4,即文档的第四个单词是“加盟”,其余的相似。

这个倒排索引已是一个很是完备的索引系统,实际搜索系统的索引结构基本如此。

参考文档:https://blog.csdn.net/starzhou/article/details/87519973#comments,并对有些图的位置作了相应调整。