倒排索引和正排索引
倒排索引是什么?
倒排索引 也被称作反向索引(inverted index),是用于提高数据检索速度的一种数据结构,空间消耗比较大。倒排索引首先将检索文档进行分词得到多个词语/词条,然后将词语和文档 ID 建立关联,从而提高检索效率。
分词就是对一段文本,通过规则或者算法分出多个词,每个词作为搜索的最细粒度一个个单字或者 单词。分词的目的主要是为了搜索,尤其在数据量大的情况下,分词的实现可以快速、高效的筛选 出相关性高的文档内容。
如下图所示,倒排索引使用 词语/词条(Term) 来作为索引关键字,并同时记录了哪些 文档(Document) 中有这个词语。
文档(Document)****:用来搜索的数据,其中的每一条数据就是一个文档。例如一个商品信息、商家信息、一页网页的内容。
词语/词条(Term)****:对文档数据或用户搜索数据,利用某种算法分词,得到的具备含义的词语就是词条。例如 ''数据库索引可以大幅提高查询速度" 这段话被中文分词器 IK Analyzer 细粒度分词后得到[数据库,索引,可以,大幅,提高,查询,速度]。
词典(****Term Dictionary):Term 的集合。
Lucene 就是基于倒排索引来做的全文检索,并且 ElasticSearch 还对倒排索引做了进一步优化。
倒排索引的创建和检索流程了解么?
这里只是简单介绍一下倒排索引的创建和检索流程,实际应用中,远比下面介绍的复杂,不过,大体原理还是一样的。
倒排索引创建流程:
- 建立文档列表,每个文档都有一个唯一的文档 ID 与之对应。
- 通过分词器对文档进行分词,生成类似于 <词语,文档ID> 的一组组数据。
- 将词语作为索引关键字,记录下词语和文档的对应关系,也就是哪些文档中包含了该词语。
这里可以记录更多信息比如词语的位置、词语出现的频率,这样可以方便高亮显示以及对搜索结果进行 排序(后文会介绍到)。
Lucene 的倒排索引大致是下面这样的:
倒排索引检索流程:
- 根据分词查找对应文档 ID
- 根据文档 ID 找到文档
倒排索引由什么组成?
单词字典 :用于存储单词列表。一般用 B+Tree 或 Hash 拉链法存储,提高查询效率。
倒排列表 :记录单词对应的文档集合。分为:
DocID:即文档 id
TF:单词出现频率,简称词频
Position:单词在文档中出现的位置,用于检索
Offset:偏移量,记录单词开始结束位置,用于高亮显示
正排索引由什么组成?
不同于倒排索引,正排索引将文档 ID 和分词建立关联。
根据词语查询时,必须先逐条获取每个文档,然后判断文档中是否包含所需要的词语,查询效率较低。
倒排索引和正排索引的区别是什么?
正排索引:
优点:维护成本低,新增数据的时候,只要在末尾新增一个 ID
缺点:以 DocID 为索引,查询时需要扫描所有词语,一个一个比较,直至查到关键词,查询效率较低。
倒排索引:
优点:建立分词和 DocID 关系,大大提高查询效率
缺点:建立倒排索引的成本高。并且,维护起来也比较麻烦,因为文档的每次更新都意味着倒排索 引的重建。还有一些搜索精度的问题,比如搜索dogs 和 dog 想要相同匹配结果,这时就需要合适的分词器了
Elasticsearch 可以针对某些字段不做索引吗?
文档会被序列化为字段组成的 JSON 格式保存在 ES中。我们可以针对某些字段不做索引。
这样可以节省存储空间,但是,同时也会让字段无法被搜索。