走近 ElasticSearch (二)——Document概念、倒排索引原理与分词介绍

一、前言

(知识搬运工
走近 ElasticSearch (一)——基本概念与架构设计
走近 ElasticSearch (二)——Document概念、倒排索引原理与分词
走近 ElasticSearch (三)——Mapping设计与Search API 介绍

二、Document 介绍

1. Document 数据类型

Json Object,由字段(Field)组成,常见数据类型如下:

  • 字符串: text, keyword
  • 数值型: long, integer, shot, byte, double, float,haf_float, scaled_float
  • 布尔: boolean
  • 日期: date
  • 二进制: binary
  • 范围类型: integer_range, float_range, long_range, double_range, date_range, ip_range
  • 还有其他数据类型:
    • 嵌套类型: nested
    • 对象类型: object
    • 数组类型: Array
    • 地理类型: geo_point, geo_shape
    • 自动补全类型: completion
    • 多字段特性:multi-fields

2. Document 创建

每个文档有唯一的 id 标示。两种方式:自行指定;es自动生成
以es自动生成索引为例:
在这里插入图片描述在这里插入图片描述
文档元数据解释:

  • _index: 文档所在的索引名
  • _type: 文档所在的类型名
  • _id: 文档唯一id
  • _uid: 组合 id, 由 _type 和 _id 组成(6.x _type 不再起作用, 同_id一样)
  • _source: 文档的原始 Json 数据,可以从这里获取每个字段的内容
  • _all: 整合所有字段内容到该字段,默认禁用

注意:创建文档时,如果索引不存在,es 会自动创建对应的 index 和 type。建议在创建索引时,定义 mapping。

使用 POST _bulk 一次创建多个文档,从而减少网络传输开销,提升写入速率

3. Document 查询

指定要查询的文档id
在这里插入图片描述
搜索索引文档,用到_search
在这里插入图片描述在这里插入图片描述

三、倒排索引与分词

1. 倒排索引

1.1 概念

在这里插入图片描述
倒排索引是搜索引擎到核心,主要包括两部分:

  • 单词词典(Term Dictionary)
    • 记录所有文档的单词,一般都比较大
    • 记录单词到倒排列表的关联信息(文档ID)
  • 倒排列表(Posting List):
    • 记录了单词对应的文档集合,由倒排索引项(Posting)组成

单词词典的实现一般是 B+ Tree
在这里插入图片描述
倒排索引项(Posting)主要包含如下信息:

  • 文档Id,用于获取原始信息
  • 单词频率(TF, Term Frequency),记录该单词在该文档中的出现次数,用于后续相关性算法
  • 位置(Position),记录单词在文档中的分词位置(多个),用于做词语搜索(Phrase Query)
  • 偏移(Offset),记录单词在文档的开始和结束位置,用于做高亮显示

在这里插入图片描述

在这里插入图片描述

1.2 索引的位置与粒度

倒排索引的位置:
Cluster->Node->Shard->segment->Index
在这里插入图片描述
为了优化搜索,segment不仅只提供了倒排,还提供了document values field cache 解决:排序、聚合等问题

对于索引的构建粒度,是按照字段来构建的,即:每个字段会有自己的倒排索引,类似下图:
在这里插入图片描述

1.3 ES集群中操作索引过程

ES引擎把文档数据写入到倒排索引(Inverted Index)的数据结构中,建立起 分词 (Term)—> 文档(Document) 映射关系。
然后这些倒排索引会存放在段(segment)中,段的写入会落盘,缓存buffer会实时更新。
具体的操作可分为写操作、读操作、更新操作

  • 写操作: 写操作必须在primary shard完全成功后才能拷贝至其对应的replicas上,默认情况下主分片。等待所有备份完成索引后才返回客户端。
    在这里插入图片描述
    1、客户端向Node1 发送索引文档请求
    2、Node1 根据文档ID(_id字段)计算出该文档应该属于shard0,然后请求路由到Node3的P0分片上
    3、Node3在P0上执行了请求。如果请求成功,则将请求并行的路由至Node1,Node2的R0上。当所有的Replicas报告成功后,Node3向请求的Node(Node1)发送成功报告,Node1再报告至Client。
    当客户端收到执行成功后,操作已经在Primary shard和所有的replica shards上执行成功了
  • 读操作: 一个文档可以在primary shard和所有的replica shard上读取
    在这里插入图片描述
    1.客户端发送Get请求到NODE1。
    2.NODE1根据文档ID(_id字段)计算出该文档应该属于shard0,且shard 0的所有拷贝存在于所有3个节点上。这次,它将请求路由至NODE2。
    3.NODE2将文档返回给NODE1,NODE1将文档返回给客户端。 对于读请求,请求节点(NODE1)将在每次请求到来时都选择一个不同的replica shard来达到负载均衡。使用轮询策略轮询所有的replica shards。
  • 更新操作,结合了以上的两个操作:读、写
    在这里插入图片描述
    1.客户端发送更新操作请求至NODE1
    2.NODE1将请求路由至NODE3,Primary shard所在的位置
    3.NODE3从P0读取文档,改变source字段的JSON内容,然后试图重新对修改后的数据在P0做索引。如果此时这个文档已经被其他的进程修改了,那么它将重新执行3步骤,这个过程如果超过了retryon_conflict设置的次数,就放弃。
    4.如果NODE3成功更新了文档,它将并行的将新版本的文档同步到NODE1和NODE2的replica shards重新建立索引。一旦所有的replica shards报告成功,NODE3向被请求的节点(NODE1)返回成功,然后NODE1向客户端返回成功。

2. 分词

分词是指将文本转换成一系列单词(term or token)的过程,也可以叫做文本分析,在 es 里面成为 Analysis,如下图所示:
在这里插入图片描述

2.1 分词器组成

分词器是 es 中专门处理分词的组建,英文为 Analyzer,它的组成如下:

  • Character Filters:针对原始文本进行处理,比如去除 html 特殊标记符
  • Tokenizer:将原始文本按照一定规则切分为单词
  • Token Filters:针对 tokenizer 处理的单词再加工,比如转小写,删除或新增等处理
    分词器调用顺序:
    在这里插入图片描述

2.2 调参:测试我们配置的分词器

es 提供了一个测试分词的 api 接口,方便验证分词效果,endpoint 是 _analyze。
对此我们可以使用三种方式进行测试:

  • 直接指定 analyzer 进行测试,接口如下:
    在这里插入图片描述
  • 直接指定索引中的字段进行测试,接口如下:
    在这里插入图片描述
  • 自定义分词器进行测试,接口如下:
    在这里插入图片描述

2.3 分词器种类

es自带如下的分词器:Standard、Simple、Whitespace、Stop、Keyword(不分词,直接将输入作为一个单词输出)、Pattern、Language
常用中文分词器:

  • ik(下载地址
    • 可自定义词库,支持热更新分词词典
  • jieba(下载地址
    • 支持繁体分词、自定义词典、并行分词等。python 中最流行的分词系统,支持分词和词性标注
      基于自然语言处理的分词系统
  • Hanlp:由一系列模型与算法组成的Java工具包,目标是普及自然语言处理在生成环境中的应用
  • THULAC:清华大学自然语言处理实验室推出的一套中文词法分析工具包,具有中文分词和词性标注功能

2.4 分词器使用说明

分词会在如下两个时机使用:

  • 创建或更新文档时(Index Time),会对相应的文档进行分词处理
  • 查询时(Search Time),会对查询语句进行分词

对于创建或更新索引:我们可以通过配置 Index Mapping 中每个字段的 analyzer 属性实现指定分词器(默认 standar 分词器);
对于查询时分词,通过 index mapping 设置 search_analyzer 实现
在这里插入图片描述

参考

一篇文章总结语言处理中的分词问题

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章