全文检索和倒排索引
一、什么是全文检索
我们生活中的数据通常可以分为两类:
结构化数据:有固定格式和固定长度。例如成绩单、工资条、花名册等等。
非结构化数据:无固定格式,无固定长度。例如邮件、会议纪要、通知书等等。非结构化数据也叫全文数据。
对结构化数据的搜索:可以把数据导入数据库表中,通过sql语句进行搜索。
对非结构化数据的搜索:有两种方法。
一种是顺序扫描,例如查找内容包含某一个字符串的文件,则要扫描所有的文档。如果遇到特大文件,这种方式就会很慢。
那有没有优化的方法呢?结构化数据使用了一定的搜索加速算法,可以提升检索速度,那么把非结构化数据尽量转变成结构化数据,是不是就可以了?因此我们又了第二种方法的思路:即把非结构化数据的部分信息提取出来,重新组织,使其具有一定的结构。
这部分从非结构化数据中提取出的然后重新组织的信息,我们称之索引。
举个例子,我们都使用过现代汉语字典,现代汉语字典的内容都是对汉字的解释,每个汉字有拼音、释义、词语、例句等等,都是非结构化的信息,但是每个汉字的拼音和部首是结构化的,通过把汉字的拼音和部首提取出来,组成拼音检索表和部首检索表,从而可以很快的找到汉字所在的页码,也就可以找到汉字的释义、词语和例句了。
这里拼音和部首就是索引。
这种先建立索引,再对索引进行搜索的过程就叫全文检索(Full-text Search)。
二、全文检索的过程
全文检索的过程分为两个部分:1.创建索引:把非结构化的数据和结构化的数据,整理并提取信息,创建索引的过程。
2.数据检索:根据用户的查询请求,搜索创建的索引,根据索引找到对应的数据。
创建索引的过程是很耗时,但是是一次性的,提供的查询速度是非常快的。一次索引,多次使用。
首先我们确定一下什么是索引?
我们想一想字段中的部首检索表,某一个部首下,有汉字列表,每个汉字对应多个页码。根据部首我们能快速找到汉字在哪个位置。这个部首检索表,就是索引。简单来说,索引中存储的是数据的部分信息和数据所在位置的对应关系,并能返回查询到所有的数据。
在现代搜索引擎中,索引设计的目的是为了方便(加速)检索。在一般的检索系统一次检索由以下两步组成:
1.根据关键词(token)检索包含token的文档Id根据文档ID检索到文档内容。
2.根据文档ID检索到文档内容
第一个步骤称为反向索引或倒排索引,即inverted index。
第二个步骤称为正向索引或正排索引,即forward index。1.正排索引: 正排索引是指文档ID为key,表中记录每个关键词出现的次数,查找时扫描表中的每个文档中字的信息,直到找到所有包含查询关键字的文档。当我们要根据某个关键词查询文档时,只能扫描索引库中所有的文档,然后根据某种方式进行排序返回。在面对海量数据的时候,这种方式无疑效率很低。
2.倒排索引:倒排索引是实现“单词-文档矩阵”的一种具体存储形式,通过倒排索引,可以根据单词快速获取包含这个单词的文档列表。倒排索引主要由两个部分组成:“单词词典”和“倒排文件”。
单词词典(Lexicon):搜索引擎的通常索引单位是单词,单词词典是由文档集合中出现过的所有单词构成的字符串集合,单词词典内每条索引项记载单词本身的一些信息以及指向“倒排列表”的指针。 倒排列表(PostingList):倒排列表记载了出现过某个单词的所有文档的文档列表及单词在该文档中出现的位置信息,每条记录称为一个倒排项(Posting)。根据倒排列表,即可获知哪些文档包含某个单词。 倒排文件(Inverted File):所有单词的倒排列表往往顺序地存储在磁盘的某个文件里,这个文件即被称之为倒排文件,倒排文件是存储倒排索引的物理文件。
总结来说,正排索引是文档id到词的映射,倒排索引是词到文档id的映射。