Elastic Stack从入门到实践之Elasticsearch

大数据 Alan 4年前 (2020-08-24) 4949次浏览 0个评论 扫描二维码

Elasticsearch 入门

常见术语

  • 文档 Document:用户存储在 es 中的数据文档(类似数据库中的行)
  • 索引 Index:由具有相同字段的文档列表组成(类似数据库的表)
  • 节点 Node:一个 Elasticsearch 的运行实例,是集群的构成单元
  • 集群 Cluster:由一个或多个节点组成,对外提供服务

Document

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

  • 字符串:text, keyword
  • 数值型:long, integer, short, byte, double, float, half_float, scaled_float
  • 布尔:boolean
  • 日期:date
  • 二进制:binary
  • 范围类型:integer_range, float_range, long_range, double_range, date_range

每个文档有唯一的id 标识

Document MetaData

元数据

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

Index

  • 索引中存储具有相同结构的文档(Document)
    每个索引都有自己的 mapping 定义,用于定义字段名和类型
  • 一个集群可以有多个索引,比如:
    Nginx 日志在存储的时候可以按照日期每天生成一个索引来存储:

    • nginx-log-01
    • nginx-log-02

Rest API

Elasticsearch 集群对外提供 RESTful API

  • REST – REpresentational State Transfer
  • URI指定资源,如 Index, Document等
  • Http Method 指明资源操作类型,如 GET、POST、PUT、DELETE等

常用两种交互方式

  • Curl 命令行
  • Kibana DevTools

索引API

es 有专门的 Index API,用于创建、更新、删除索引配置等

创建索引 API:PUT /test_index (蓝色部分为索引名)

查看现有索引:GET _cat/indices

删除索引:DELETE /test_index

文档 Document API

es 有专门的 Document API

  • 创建文档
    • 指定 id 创建文档(新版中type 已被取消,可使用/test_index/_doc/1, /test_index/_create/1)
    • 不指定 id 创建文档 api(新版中为/test_index/_doc):
    • 批量创建文档(_bulk, index 与 create的区别是即使文档存在也不会报错,而是进行覆盖,新版中无需再指定_type)
  •  查询文档
    • 指定要查询的文档 id(同样在新版中使用_doc)
    • 搜索所有文档,使用_search:
    • 一次查询多个文档(_mget)
  • 更新文档
  • 删除文档

Elasticsearch倒排索引与分词

正排索引:文档 id 到文档内容、单词的关联关系(下图左侧)

倒排索引:单词到文档 id 的关联关系(下图右侧)

Elastic Stack从入门到实践之Elasticsearch

倒排索引组成

倒排索引是搜索引擎的核心,主要包含两部分:

倒排列表(Posting )主要包含如下信息:

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

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

分词

分词是指将文本转换成一系列单词(term or token)的过程,也可以叫做文本分析,在 es 里称为 Analysis

分词器是 es 中专门处理分词的组件,英文为 Analyzer,组成如下(按从上到下的顺序):

  • Character Filters:针对原始文本进行处理,比如去除 html 特殊标记符
  • Tokenizer:将原始文本按照一定规则切分为单词
  • Token Filters:针对 tokenizer 处理的单词进行再加工,比如转小写、删除(如 stop words)或新增(如近义词、同义词)等处理

Analyze API

es 提供了一个测试分词的 API 接口,方便验证分词效果,endpoint 是_analyze

  • 可以直接指定 analyzer 进行测试
  • 可以直接指定索引中的字段进行测试
  • 可以自定义分词器进行测试

预定义分词器

es 自带分词器

  • Standard
    • 默认分词器
    • 按词切分,支持多语言
    • 小写处理
  • Simple
    • 按照非字母切分
    • 小写处理
  • Whitespace
    • 按照空格切分
  • Stop
    • Stop Word 指语气助词等修饰性的词语,比如 the、an、的、这等等
    • 相比 Simple Analyzer 多了 Stop Word 处理
  • Keyword
    • 不分词,直接将输入作为一个单词输出
  • Pattern
    • 通过正则表达式自定义分割符
    • 默认是\W+,即非字词的符号作为分隔符
  • Language
    • 提供了30+常见语言的分词器
    • arabic, armenian, basque, bengali, brazilian, bulgarian, catalan, cjk, czech, danish, dutch, english…

中文分词

难点

  • 中文分词指的是将一个汉字序列切分成一个一个单独的词。在英文中,单词之间是以空格作为自然分界符,汉语中词没有一个形式上的分界符。
  • 上下文不同,分词结果迥异,比如交叉歧义问题,下面两种分词都合理:
    • 乒乓球拍/卖/完了
    • 乒乓球/拍卖/完了
  • https://mp.weixin.qq.com/s/uCpuJPQ6UDfPG44hiUlb3g

常用分词系统

基于自然语言处理的分词系统

自定义分词

当自带的分词无法满足需求时,可以自定义分词

  • 通过自定义 Character Filters、Tokenizer 和 Token Filter 实现

Character Filters

  • 在 Tokenizer 之前对原始文本进行处理,例如增加、删除或替换字符等
  • 自带的如下
    • HTML Strip 去除 html 标签和转换 html 实体
    • Mapping 进行字符替换操作
    • Pattern Replace 进行正则匹配替换
  • 会影响后续 tokenizer 解析的 position 和 offset 信息

Tokenizer

将原始文本按照一定规则切分为单词(term or token)

自带的如下:

  • standard 按照单词进行分割
  • letter 按照非字符类进行分割
  • whitespace 按照空格进行分割
  • UAX URL Email 按照 standard 分割,但不会分割邮箱和 URL
  • NGram 和 Edge NGram 连词分割
  • Path Hierarchy按照文件路径进行切割

Token Filters

对于 tokenizer 输出的单词(term) 进行增加、删除、修改等操作

自带的如下:

  • lowercase 将所有 term 转换为小写
  • stop 删除 stop words
  • NGram 和 Edge NGram 连词分割
  • Synonym 添加近义词 term

自定义分词 API

自定义分词需要在索引的配置中设定

自定义分词验证

示例1

示例2

分词使用说明

分词使用的两个时机:

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

索引时分词是通过配置 Index Mapping 中的每个字段的 analyzer 属性实现的,不指定分词时,使用默认 standard,如下:

查询时分词的指定方式有如下几种:

  • 查询时通过 analyzer 指定分词器
  • 通过 index mapping 设置 search_analyzer 实现

一般不需要特别指定查询时分词器,直接使用索引时分词器即可,否则会出现与索引无法匹配的情况

分词的使用建议

  • 明确字段是否需要分词,不需要分词的字段将 type 设置为 keyword,可以节省空间、提高写性能
  • 善用_analyze API,查看文档的具体分词结果
  • 动手测试

Mapping 设置

Mapping类似数据库中的表结构定义,主要作用如下:

  • 定义 Index 下的字段名(Field Name)
  • 定义字段的类型,比如数值型、字符串型、布尔型等
  • 定义倒排索引相关的配置,比如是否索引、记录 position 等

自定义 Mapping

Mapping 中的字段类型一旦设定后,禁止直接修改,原因是 Lucene 实现的倒排索引生成后不允许修改。修改需重新建立新的索引,然后做 reindex 操作。

允许新增字段,通过 dynamic 参数来控制字段的新增

  • true(默认)允许自动新增字段
  • false 不允许自动新增字段,但是文档可以正常写入,但无法对字段进行查询操作
  • strict 文档不能写入,报错

copy_to

  • 将该字段的值复制到目标字段,实现类似_all 的作用
  • 不会出现在_source 中,只用来搜索

index

控制当前字段是否索引,默认为 true,即记录索引,false 不记录,即不可搜索

index_options

  • index_options 用于控制倒排索引记录的内容,有如下4种配置
    • docs 只记录 doc id
    • freqs 记录 doc id 和 term frequencies
    • positions 记录 doc id、term frequencies 和 term position
    • offsets 记录 doc id、term frequencies、term position 和 character offsets
  • text 类型默认配置为 positions,其他默认为 docs
  • 记录内容越多,占用空间越大

null_value

当字段遇到 null 值时的处理策略,默认为 null,即空值,此时 es 会忽略该值。可以通过设定该值设定字段的默认值

有关 mapping 更多参数请见官方文档

数据类型

核心数据类型

  • 字符串型 text、keyword
  • 数值型 long, integer, short, byte, double, float, half_float, scaled_float
  • 日期类型 date
  • 布尔类型 boolean
  • 二进制类型 binary
  • 范围类型 integer_range, float_range, long_range, double_range, date_range

复杂数据类型

  • 数组类型 array
  • 对象类型 object
  • 嵌套类型 nested object

地理位置数据类型

  • geo_point
  • geo_shape

专用类型

  • 记录 ip 地址 ip
  • 实现自动补全 completion
  • 记录分词数 token_count
  • 记录字符串 hash 值 murmur3
  • percolator
  • join

多字段特性 multi-fields

  • 允许对同一字段采用不同的配置,比如分词,常见例子如对人名实现拼音搜索,只需要在人名中新增一个子字段为 pinyin 即可

更多有关数据类型的介绍请见官方文档

Dynamic Mapping

es 可以自动识别文档字段类型,从而降低用户使用成本

es 是依靠 JSON 文档的字段类型来实现自动识别字段类型,支持的类型如下:

Elastic Stack从入门到实践之Elasticsearch

日期的自动识别可以自行配置日期格式,以满足各种需求

  • 默认是[“strict_date_optional_time”,”yyyy/MM/dd HH:mm:ss Z||yyyy/MM/dd Z”]
  • strict_date_optional_time是 ISO datetime 的格式,完整格式类似下面:
    • YYYY-MM-DDThh:mm:ssTZD(eg 1997-07-16T19:20:30+01:00)
  • dynamic_date_formats 可以自定义日期类型
  • date_detection 可以关闭日期自动识别的机制

字符串是数字时,默认不会自动识别为整型,因为字符串中出现数字是完全合理的

  • numeric_detection 可以开启字符串中数字的自动识别

Dynamic Templates

允许根据 es 自动识别的数据类型、字段名等来动态设定字段类型,可以实现如下效果

  • 所有字符串类型都设定为 keyword 类型,即默认不分词
  • 所有以 message 开头的字段都设定为text 类型,即分词
  • 所有以 long_开头的字段都设定为 long 类型
  • 所有自动匹配为 double 类型的都设定为 float 类型,以节省空间

匹配规则一般有如下几个参数:

  • match_mapping_type 匹配 es 自动识别的字段类型,如 boolean,long,string 等
  • match, unmatch 匹配字段名
  • path_match, path_unmatch 匹配路径

自定义 Mapping 的操作步骤如下:

  1. 写入一条文档到 es 的临时索引中,获取 es 自动生成的 mapping
  2. 修改步骤1得到的 mapping,自定义相关配置
  3. 使用步骤2的 mapping 创建实际所需索引

索引模板,英文为 Index Template,主要用于在新建索引时自动应用预先设定的配置,简化索引创建的操作步骤

  • 可以设定索引的配置和 mapping
  • 可以有多个模板,根据 order 设置,order 在的覆盖小的配置

Search API

实现对 es中存储的数据进行查询分析,endpoint 为_search,如下所示:

查询主要有两种形式

  • URI Search
    • 操作简便,方便对完命令行测试
    • 仅包含部分查询语法
  • Request Body Search
    • es 提供的完备查询语法 Query DSL(Domain Specific Language)

https://github.com/mobz/elasticsearch-head

https://github.com/medcl/elasticsearch-analysis-ik

常见问题

1、You are not authorized to access Ingest Manager. Ingest Manager requires superuser privileges.

此时使用默认超级用户 elastic进行登录

2、跨域配置

 

 

喜欢 (0)
[]
分享 (0)
发表我的评论
取消评论

表情 贴图 加粗 删除线 居中 斜体 签到

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址