Elasticsearch 倒排索引

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Elasticsearch 倒排索引相关的知识,希望对你有一定的参考价值。

参考技术A 之前我们已经了解过,Elasticsearch 是一个基于 Lucene 实现的分布式全文检索引擎,其实 Elasticsearch 倒排索引就是 Lucene 的倒排索引。数据检索是 ES 的一项核心功能,它的底层实现也是离不开倒排索引的,通过倒排索引技术可以提高数据的检索效率,理解倒排索引的原理很重要。

那什么是倒排索引,我们该如何理解它呢?

我们能进行数据检索的前提条件是,已经创建好了索引库,并给里边添加了文档数据。所以我们可以按照 创建索引库 、 添加文档 、 数据检索 这个顺序来认识倒排索引。

首先是创建索引库,我们之前已经安装好了 IK 分词器,这里我们创建一个 test 索引,它只有一个 content 字段,添加文档时字段的分词模式是 ik_max_word ,检索时关键字的分词模式是 ik_smart :

字段的分词模式会影响最终生成的倒排索引。不了解分词器的可以参考 Elasticsearch 中文分词器插件 。

创建好了索引,我们来添加一条文档数据:

添加文档数据时,ES 会根据字段的分词模式将字段的值拆分成多个 词条 (Term)(或者称作词项),创建索引库时我们指定了 content 字段分词模式为 ik_max_word ,则会生成如下的词条:

接下来就是建立倒排索引了,在这之前我们先了解两个概念 词条字典 (Term Dictionary)、 倒排列表 (Posting List):

ES 的倒排索引就是由 词条字典 和 倒排列表 两部分组成的。如下就是一个简易版的倒排索引,倒排列表项只有词条对应的文档 id:

一个词条对应一个倒排索引项。ES 会给每个字段都建立一个倒排索引。

我们再添加一条文档数据:

根据上边的原理,最终 content 字段的倒排索引会被更新成如下结构:

前边已经添加了文档数据,同时也生成了倒排索引,接下来就是检索数据了。在这之前还有一个知识点需要了解,那就是 词条索引 (Term Index),词条索引一般只存储各个 词条 的前缀(第一个字符),它和字条字典对应。之所以需要词条索引,是因为 词条字典 一般都很大,不适合保存在内存中而是存储在磁盘中,检索数据时根据关键字的前缀匹配到词条索引,再根据词条索引定位到关键字在倒排索引的词条字典中大致的位置,然后进一步在词条字典中通过二分查找定位到具体的词条,这样避免了直接遍历词条字典来点位词条,大幅减少了磁盘的读取,提高了效率。

定位到了词条,就能在倒排索引中找到对应的倒排列表项,进而就知道了对应的文档 id,有了文档 id 自然也就找到了文档,这也就是 ES 检索数据大致的原理。

如下我们查询包含 十二 的文档数据:

由于我们创建索引库时指定了检索时关键字的分词模式是 ik_smart ,所以 十二 被分词后还是 十二 ,再结合上边的原理,以 十二 为关键字最终可以查询到 id 为 1、2 的文档数据:

这篇最好能结合 Elasticsearch 中文分词器插件 一起看,这样能更容易理解些。

新手上路,不合理的地方还望大佬指点。

以上是关于Elasticsearch 倒排索引的主要内容,如果未能解决你的问题,请参考以下文章

ES基本原理

Elasticsearch:运用 doc-value-only 字段来实现更快的索引速度并节省空间 - Elastic Stack 8.1

Elasticsearch:运用 doc-value-only 字段来实现更快的索引速度并节省空间 - Elastic Stack 8.1

Elastic 之倒排索引

Elasticsearch 倒排索引

Elasticsearch7.8.0版本进阶——倒排索引