Elasticsearch倒排索引详解
Posted 一只懒得睁眼的猫
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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
- 倒排索引的概念
在介绍倒排索引之前,我们先回忆几个基本的概念.
文档:通常情况下,我们会把一个具体的目标进行一定的整理,然后以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)。根据倒排列表,即可获知哪些文档包含某个单词。
- 倒排索引的直观了解
正排索引:
倒排索引:
单词ID:记录每个单词的单词编号;单词:对应的单词;文档频率:代表文档集合中有多少个文档包含某个单词;
倒排列表:包含单词ID及其他必要信息,具体信息如下:
DocId:单词出现的文档id;TF:单词在某个文档中出现的次数;POS:单词在文档中出现的位置;
以单词“加盟”为例,其单词编号为6,文档频率为3,代表整个文档集合中有三个文档包含这个单词,对应的倒排列表为(2;1;<4>),(3;1;<7>),(5;1;<5>),含义是在文档2,3,5出现过
这个单词,在每个文档的出现过1次,单词“加盟”在第一个文档的POS是4,即文档的第四个单词是“加盟”,其他的类似。
这个倒排索引已经是一个非常完备的索引系统,实际搜索系统的索引结构基本如此。
- 基于倒排索引的ES数据查询过程
如上面介绍:
ElasticSearch引擎把文档数据写入到倒排索引(Inverted Index)的数据结构中,倒排索引建立的是分词(Term)和文档(Document)之间的映射关系,在倒排索引中,数据是面向词
(Term)而不是面向文档的。一个倒排索引由文档中所有不重复词的列表构成,对于其中每个词,有一个包含它的文档列表,示例,对以下三个文档去除停用词后构造倒排索引:
倒排索引的查询过程,假设我们要查询包含“搜索引擎”的文档,具体步骤如下:
-
通过倒排索引获得“搜索引擎”对应的文档id列表,有1,3;
-
通过正排索引查询1和3的完整内容;
-
返回最终结果.
-
单词词典的数据结构
当我们通过ES来查询某个关键字时,ES会先从单词词典中找到这个关键字对应的元素,然后,从元素中的指针定位到倒排列表中的某个倒排项,就能从倒排项中,快速知道,所有包含该关键字的
文档列表。所以,单词词典采用什么样的数据结构来存储,是关系到查询速度的重要因素之一;思考:如果这里有上千万的记录呢?如何通过term来查找呢?
一般来说,单词词典通常的数据结构有两种,一种是哈希+链表,另一种是树。
方式1:哈希+链表
哈希+链表这种形式,和JAVA中老的HashMap的数组结构形式是一样的。在创建索引时,会根据单词的哈希值,计算出单词所在位置,然后存放到该位置的链表中。
方式2:树
树是另外一种ES经常用在单词词典中的数据结构,通常是B或B+树。这种数据结构,和mysql数据库的索引是同样的,也是一种查询高效的数据结构。
B+树内部结点存索引,叶子结点存数据,这里的 单词词典就是B+树索引,倒排列表就是数据,整合在一起后如下所示:
ES存储的是一个JSON格式的文档,其中包含多个字段,每个字段会有自己的倒排索引!!!!
-
倒排索引的创建—分词器
我们交给ES的是文档,ES回馈给我们的是倒排索引,那么,ES是如何把文档变成倒排索引的呢?一般而言,会经过三个步骤: -
预处理。首先,要对文档内容进行一定程序的整理,如过滤掉其中的html标签等,这个过程,称之为预处理;
-
分词。根据特定规则,将预处理后的内容拆分成一个个单词,这个过程,称之为分词;
-
标准化。分词后,文档变成了一个单词的集合,但是,在这个集合中,可能存在一些无意义的,错误的,或重复的单词,那么,在标准化阶段,就是要把这些内容处理掉,以避免这些单词进入词典,
影响词典的质量。在分词阶段,起到关键作用的就是分词器,并且,分词阶段只能有一个分词器。你可以使用ES内置的分词器,也可以第三方提供的分词器或者自定义分词器。
- 分词器介绍
通常情况下,ES内置的分词器对中文是不友好的,所以,第三方分词器或者自定义分词器,对于中文搜索站点来说,是必须要做的。我们来认识一下ES内置的几个分词器,以及一些第三方分词器。
ES自带的分词器
- Standard Analyzer:是默认的分词器,会按词进行拆分,并做英文大写到小写的转换,如果是中文,会按照单字拆分。
。。。。。。。。
。。。。。。。。
以上就是ES自带的分词器,我们发现,这些分词器基本上都无法满足业务需要,尤其是包含中文搜索的业务。那么,我们就需要引入一些第三方的分词器来帮助ES完成分词。
第三方分词器
- IK:实现中英文单词的切分,可自定义词库,支持热更新分词词典。
。。。。。。。
。。。。。。。
以上是关于Elasticsearch倒排索引详解的主要内容,如果未能解决你的问题,请参考以下文章
ElasticSearch01_简介安装es以及kibana详解倒排索引检索es基本信息增删改查文档
ElasticSearch01_简介安装es以及kibana详解倒排索引检索es基本信息增删改查文档
ElasticSearch01_简介详解倒排索引安装es以及kibana检索es基本信息增删改查文档