Lucene:基于传统全文检索引擎的倒排索引,并实现了分块索引。与倒排所引相对立的是正排索引,也成为正向所引。本文将简单介绍。
1 正排索引(forward index)
由key查询实体的过程,是正排索引.
在搜索引擎中每个文件都对应一个文件ID,文件内容被表示为一系列关键词的集合 Map< id,list< item>>,能够由id快速找到内容的一个数据结构。
2 倒排索引(inverted index)
由item查询key的过程,是倒排索引。
倒排索引可以理解为Map< item, list< id>>,能够由查询词快速找到包含这个查询词的文件的数据结构。倒排索引主要由两个部分组成:“单词词典”和“倒排文件”。
倒排索引基本概念
文档(Document):一般搜索引擎的处理对象是互联网网页,而文档这个概念要更宽泛些,代表以文本形式存在的存储对象,相比网页来说,涵盖更多种形式,比如Word,PDF,html,XML等不同格式的文件都可以称之为文档。
文档集合(Document Collection):由若干文档构成的集合称之为文档集合。比如海量的互联网网页或者说大量的电子邮件都是文档集合的具体例子。
文档编号(Document ID):将文档集合内每个文档赋予一个唯一的内部编号,以此编号来作为这个文档的唯一标识,这样方便内部处理,每个文档的内部编号即称之为“文档编号”,后文有时会用DocID来便捷地代表文档编号。
单词编号(Word ID):与文档编号类似,搜索引擎内部以唯一的编号来表征某个单词,单词编号可以作为某个单词的唯一表征。
单词词典(Lexicon):搜索引擎的通常索引单位是单词,单词词典是由文档集合中出现过的所有单词构成的字符串集合,单词词典内每条索引项记载单词本身的一些信息以及指向“倒排列表”的指针。
倒排列表(PostingList):倒排列表记载了出现过某个单词的所有文档的文档列表及单词在该文档中出现的位置信息,每条记录称为一个倒排项(Posting)。根据倒排列表,即可获知哪些文档包含某个单词。
倒排文件(Inverted File):所有单词的倒排列表往往顺序地存储在磁盘的某个文件里,这个文件即被称之为倒排文件,倒排文件是存储倒排索引的物理文件。
关于这些概念之间的关系,通过下图可以比较清晰的看出来。
3 简单举例
针对倒排所引和正排索引,做简单介绍,例如以下两个文档:
文档1:word1,word2,word3......
文档2:word2,word3,word5....
文档1和文档2 手续经过分词并记录词语在文档的位置和出现的次数,之后得到两个词语集合。
正排索引的结构如下:
“文档1”的ID > 单词1:出现次数,出现位置列表;单词2:出现次数,出现位置列表;
“文档2”的ID > 单词1:出现次数,出现位置列表;单词2:出现次数,出现位置列表;
倒排索引的结构如下:
4 实际举例
文档编号(id) | 文档内容 |
---|---|
1 | 我喜欢数学 |
2 | 我喜欢编程 |
3 | 我考试数学成绩很好 |
4 | 编程太难了 |
分词之后的正排索引Map< id, list< item>>
文档编号(id) | 分词后的集合(list< item>) |
---|---|
1 | {我,喜欢,数学} |
2 | {我,喜欢,编程} |
3 | {我,考试,数学,成绩,很好} |
4 | {编程,太难了} |
分词后倒排索引
- 简单的倒排索引Map< item,list< id>>
编号 | 单词(item) | 倒排列表(list< id>) |
---|---|---|
1 | 我 | 1,2,3 |
2 | 喜欢 | 1,2 |
3 | 数学 | 1,3 |
4 | 编程 | 2,4 |
5 | 考试 | 3 |
6 | 成绩 | 3 |
7 | 很好 | 3 |
8 | 太难了 | 4 |
-
有单词频率信息(TF)的倒排索引Map< item,list< (id;TF)>>
在单词对应的倒排列表中不仅记录了文档编号,还记载了单词频率信息,即这个单词在某个文档中的出现次数,之所以要记录这个信息,是因为词频信息在搜索结果排序时,计算查询和文档相似度是很重要的一个计算因子,将其记录在倒排列表中,以方便后续排序时进行分值计算。
编号 | 单词(item) | 倒排列表(list< (id;TF)>); |
---|---|---|
1 | 我 | (1;1),(2;1),(3;1) |
2 | 喜欢 | (1;1),(2,1) |
3 | 数学 | (1;1),(3;1) |
4 | 编程 | (2;1),(4;1) |
5 | 考试 | (3;1) |
6 | 成绩 | (3;1) |
7 | 很好 | (3;1) |
8 | 太难了 | (4;1) |
- 有单词频率和出现位置(pos)信息的倒排索引Map< item,list<(id;TF;< pos>)>>
编号 | 单词(item) | 倒排列表(list<(id;TF;< pos>)>); |
---|---|---|
1 | 我 | (1;1;<1>),(2;1;<1>,(3;1;<1>) |
2 | 喜欢 | (1;1;<2>),(2;1;<2>) |
3 | 数学 | (1;1;<3>),(3;1;<3>) |
4 | 编程 | (2;1;<3>),(4;1;<1>) |
5 | 考试 | (3;1;<3>) |
6 | 成绩 | (3;1;<4>) |
7 | 很好 | (3;1;<5>) |
8 | 太难了 | (4;1;<2>) |
- 单词词典(实际运行过程中,单词词典是在内存中)
编号 | 单词(item) |
---|---|
1 | 我 |
2 | 喜欢 |
3 | 数学 |
4 | 编程 |
5 | 考试 |
6 | 成绩 |
7 | 很好 |
8 | 太难了 |
5.对比
(1)倒排所有主要的作用就是召回,正排索引的作用主要是排序(计算分数)
(2)对一个大型搜索引擎,召回只是最基本、最简单的功能,所以倒排所引只占整个搜索index的20%--30%;相反正排索引真正占70--80%(其中排序的正排又占大头)
参考
2.什么是倒排索引?