Elasticsearch倒排索引详解

 这篇博客的主要目的是介绍一下ES当中的倒排索引,参考:

https://blog.csdn.net/qq_21312297/article/details/102496833

https://zhuanlan.zhihu.com/p/68092794

https://baijiahao.baidu.com/s?id=1661292466150156938&wfr=spider&for=pc

https://blog.csdn.net/jiaojiao521765146514/article/details/83750548

  1. 倒排索引的概念
    在介绍倒排索引之前,我们先回忆几个基本的概念.

文档:通常情况下,我们会把一个具体的目标进行一定的整理,然后以JSON的形式交给ES。比如商品,通常我们会把商品名称,描述,价格,库存等一系列内容整理好,交给ES。那么,

对于ES来说,这个具体的目标就是文档,JSON是ES喜欢的文档表现形式。

文档ID:为了便于对文档进行标识,ES会将接收到的文档进行编号,这个编号可以由ES自动生成,也可以由客户端指定。

那么根据文档ID和文档,我们就可以得到正排索引,即通过key找value:

单词:文档交给ES后,ES会根据设定的规则,对文档进行分析和拆分,文档将会被拆分成一个个单词。换句话说,对于ES来说,分析后的文档就是由单词组成的。

单词ID:和文档一样,ES也会对单词进行标识,标识的方式同样也是对单词进行编号。

有了以上几个概念,我们再来解释倒排索引。倒排索引,描述了从单词到文档的关联关系。利用倒排索引,可以快速的通过单词找到和该单词关联的文档列表。倒排索引由两部分组成,一个

是单词词典,一个是倒排列表。一个文档由许多的单词组成,我们交给ES的文档的越多,分析拆分后得到的单词就越多,这些单词被整理组织成一个集合,集合中的每个元素记录了单词本身

的一些相关信息以及一个指定倒排列表的指针。通过单词,我们会在倒排列表中找到一个倒排项,该倒排项中,记录了出现过该单词的所有文档ID,以及单词在文档中的位置信息。也就是说,

倒排列表,是倒排项的集合。倒排列表会以文件的形式,具体的存储在磁盘中的某个位置,这个文件,称之为倒排文件。

简单来说:通俗来讲正向索引是通过key找value,反向索引则是通过value找key。

那么在Elasticsearch当中,对于上面的正排索引,建立的倒排索引索引如下:

如上图所示:

Elasticsearch分别为每个field都建立了一个倒排索引,24,Kate, John Female这些叫term,而[1,2]就是Posting List倒排列表。Posting list就是一个int的数组,倒排列表记录了出现过

某个单词的所有文档的文档列表及单词在该文档中出现的位置信息,每条记录称为一个倒排项(Posting)。根据倒排列表,即可获知哪些文档包含某个单词。

  1. 倒排索引的直观了解
    正排索引:

倒排索引:

单词ID:记录每个单词的单词编号;单词:对应的单词;文档频率:代表文档集合中有多少个文档包含某个单词;

倒排列表:包含单词ID及其他必要信息,具体信息如下:

DocId:单词出现的文档id;TF:单词在某个文档中出现的次数;POS:单词在文档中出现的位置;

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

这个单词,在每个文档的出现过1次,单词“加盟”在第一个文档的POS是4,即文档的第四个单词是“加盟”,其他的类似。

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

  1. 基于倒排索引的ES数据查询过程
    如上面介绍:

ElasticSearch引擎把文档数据写入到倒排索引(Inverted Index)的数据结构中,倒排索引建立的是分词(Term)和文档(Document)之间的映射关系,在倒排索引中,数据是面向词

(Term)而不是面向文档的。一个倒排索引由文档中所有不重复词的列表构成,对于其中每个词,有一个包含它的文档列表,示例,对以下三个文档去除停用词后构造倒排索引:

倒排索引的查询过程,假设我们要查询包含“搜索引擎”的文档,具体步骤如下:

  1. 通过倒排索引获得“搜索引擎”对应的文档id列表,有1,3;

  2. 通过正排索引查询1和3的完整内容;

  3. 返回最终结果.

  4. 单词词典的数据结构
    当我们通过ES来查询某个关键字时,ES会先从单词词典中找到这个关键字对应的元素,然后,从元素中的指针定位到倒排列表中的某个倒排项,就能从倒排项中,快速知道,所有包含该关键字的

文档列表。所以,单词词典采用什么样的数据结构来存储,是关系到查询速度的重要因素之一;思考:如果这里有上千万的记录呢?如何通过term来查找呢?

一般来说,单词词典通常的数据结构有两种,一种是哈希+链表,另一种是树。

方式1:哈希+链表
哈希+链表这种形式,和JAVA中老的HashMap的数组结构形式是一样的。在创建索引时,会根据单词的哈希值,计算出单词所在位置,然后存放到该位置的链表中。

方式2:树
树是另外一种ES经常用在单词词典中的数据结构,通常是B或B+树。这种数据结构,和MySQL数据库的索引是同样的,也是一种查询高效的数据结构。

B+树内部结点存索引,叶子结点存数据,这里的 单词词典就是B+树索引,倒排列表就是数据,整合在一起后如下所示:

ES存储的是一个JSON格式的文档,其中包含多个字段,每个字段会有自己的倒排索引!!!!

  1. 倒排索引的创建—分词器
    我们交给ES的是文档,ES回馈给我们的是倒排索引,那么,ES是如何把文档变成倒排索引的呢?一般而言,会经过三个步骤:

  2. 预处理。首先,要对文档内容进行一定程序的整理,如过滤掉其中的html标签等,这个过程,称之为预处理;

  3. 分词。根据特定规则,将预处理后的内容拆分成一个个单词,这个过程,称之为分词;

  4. 标准化。分词后,文档变成了一个单词的集合,但是,在这个集合中,可能存在一些无意义的,错误的,或重复的单词,那么,在标准化阶段,就是要把这些内容处理掉,以避免这些单词进入词典,

影响词典的质量。在分词阶段,起到关键作用的就是分词器,并且,分词阶段只能有一个分词器。你可以使用ES内置的分词器,也可以第三方提供的分词器或者自定义分词器。

  1. 分词器介绍
    通常情况下,ES内置的分词器对中文是不友好的,所以,第三方分词器或者自定义分词器,对于中文搜索站点来说,是必须要做的。我们来认识一下ES内置的几个分词器,以及一些第三方分词器。

ES自带的分词器

  1. Standard Analyzer:是默认的分词器,会按词进行拆分,并做英文大写到小写的转换,如果是中文,会按照单字拆分。

。。。。。。。。

。。。。。。。。

以上就是ES自带的分词器,我们发现,这些分词器基本上都无法满足业务需要,尤其是包含中文搜索的业务。那么,我们就需要引入一些第三方的分词器来帮助ES完成分词。

第三方分词器

  1. IK:实现中英文单词的切分,可自定义词库,支持热更新分词词典。

。。。。。。。

。。。。。。。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

一只懒得睁眼的猫

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值