Elasticsearch教程 — 基本概念

Elasticsearch是什么

Elasticsearch是Elastic推出的基于Lucene的分布式、可扩展、高实时的搜索数据分析引擎
英文文档,基于7.15版本:https://www.elastic.co/guide/en/elasticsearch/reference/current/index.html

Elasticsearch特点

详细特点参考官网:https://www.elastic.co/cn/elasticsearch/features

  • 分布式、可扩展、高实时;
  • PB级别的数据;
  • 数据存储类型多样。数字、文本、地理位置、结构化数据、非结构化数据。适用于所有数据类型;
  • 标准的 RESTful 风格的 API 和 JSON;
  • Elastic三件套:Elasticsearch(搜索)、Logstash(采集)、Kibana(可视化)

Elasticsearch应用场景

  • 全文搜索引擎(搜索服务);
  • 分类筛选,特别适用大量筛选服务,例如电商列表筛选(搜索服务);
  • 日志数据,用户行为等数据分析(数据分析)
  • 大数据、实时分析、推荐系统、坐标附近的人搜索
  • 可以做为另类的数据库(数据存储);

Elasticsearch可视化工具

俗话说,工欲善其事必先利其器,虽然可直接使用命令行工具使用它,但是为了快速学习使用,推荐使用可视化工具。

  • Kibana (官方提供的可视化工具)
  • elasticsearch-head
  • ElasticHD
  • dejavu

Elasticsearch与MySQL对比

由于elasticsearch 7.0.0版本必须使用单index,单type,而在es8中彻底不支持映射类型。所以以前看别人的教程中将MySQL的数据表与es的type对于起来就不适合了。这里我说一下自己的理解,当然这里只是为了方便我们理解。

MySQL Elasticsearch
数据库Database 索引集合
表Table 索引(Index)
行(Row) 文档(Document)
列(Column) 字段(Field)
约束(schema) 映射(Mapping)

这里我使用了索引集合这个概念,当然es中是没这个概念的。我们在实际操作的过程中怎么使用这个索引集合呢?可以从索引名称上加一个前缀区分 应用名-功能名-索引名,这样应用名-*就代表一个索引集合了。

Elasticsearch基本概念

Elasticsearch 使用一种称为倒排索引的数据结构,文本字段存储在倒排索引中,数值和地理字段存储在 BKD 树中。

文档(document)

存入索引库原始的数据。比如每一条商品信息,就是一个文档。相当于MySQL中的一条记录。

查询(Query DSL)

主要是指的_serach API中的query参数
参考官方文档:https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl.html
查询就是数据呈现的过程。类似于MySQL提供的select语句。DSL是ES的核心功能,要认真学习。
Elasticsearch 提供了一个基于 JSON 的完整 Query DSL(Domain Specific Language)来定义查询。将查询 DSL 视为查询的 AST(抽象语法树),由两种类型的子句组成:

  • 叶查询子句,在特定字段中查找特定值,例如 match、term或 range查询。类似MySQL中的where id=1 这样的特定字段查询。
  • 复合查询子句,多个叶查询子句或复合查询子句组合成的子句。

某些查询子句非常耗时,需要注意些。具体参考官方文档。

搜索(search)

主要是调用_search API进行搜索。
参考官方文档:https://www.elastic.co/guide/en/elasticsearch/reference/current/search-search.html

  • 查询,可以理解成单个条件的查询,类似 where id=1
  • 搜索,可以理解成一个或多个条件的查询,类似 where id=1 and age=20

常用的搜索选项

  • Query DSL
  • 聚合(Aggregations)
  • 搜索多个数据流和索引
  • 对搜索结果进行分页
  • 检索选定的字段
  • 对搜索结果操作
  • 运行异步搜索

映射(Mapping)

映射是定义文档及其包含的字段如何存储和索引的过程。每个文档都有自己的字段集合,每个字段都有数据类型,还包括元数据字段等。可以理解成MySQL的表结构定义。

  • 动态映射,在刚开始时试验和探索数据。Elasticsearch 自动添加新字段。可以理解成根据数据自动映射。
  • 显式映射,允许您精确选择如何定义映射定义。可以理解成手动映射
  • 另外还有一种“runtime fields”是在查询时计算的字段,无需重新索引就可以改变索引结构,但会消耗部分性能。这种字段可以显示映射也可以在查询语句中映射。

Text分析(Text Analysis)

文本分析是将非结构化文本(例如电子邮件正文或产品说明)转换为针对搜索进行优化的结构化格式的过程。
Elasticsearch 在索引或搜索text字段时执行文本分析。
如果您的索引不包含text字段,则无需进一步分析;

索引模块(Index Modules)

索引模块是为每个索引创建的模块,控制与索引相关的所有方面。
索引模块可以分为静态索引static动态索引dynamic。静态索引,只能在索引创建时或者在状态为 closed index(闭合的索引)上设置。动态索引,可以使用 update-index-settings API 在状态为 live index(激活的索引)上更改它们。

索引模板(Index Modules)

Elasticsearch 7.8中引入索引模板,使用前注意ES的版本。其实可以理解成一个可重用的索引模块的定义。
两种类型的模板:索引模板组件模板。组件模板是可重用的构建块,用于配置映射、设置和别名。索引模板可以包含组件模板的集合,也可以直接指定设置、映射和别名。

数据流(Data streams)

Elasticsearch 7.9中引入的功能,使用前注意版本。
官方定义:数据流是可以跨多个索引存储仅限于追加存储时间序列数据,同时为请求提供单个命名资源。
data stream 非常适合日志,事件,指标以及其他持续生成的数据。

  • 数据流是为现有数据很少更新的用例而设计的。不能将现有文档的更新或删除请求直接发送到数据流。
  • 如果需要,可以通过直接向文档的后备索引提交请求来更新或删除文档。
  • 如果经常更新或删除现有的时间序列数据,请使用具有写索引权限的索引别名,而不是数据流。

创建数据流的步骤:

  • 创建索引生命周期策略
  • 创建组件模板
  • 创建索引模板
  • 创建数据流
  • 保护数据流

别名(Aliases)

别名是一组数据流或索引的辅助名称。别名分两种,不过需注意别名不能同时指向数据流和索引。

  • 数据流别名:指向一个或多个数据流。
  • 索引别名:指向一个或多个索引。

Ingest pipelines

Ingest管道允许您在索引之前对数据执行常见转换。例如,您可以使用管道删除字段、从文本中提取值并丰富您的数据。
管道由一系列称为处理器的可配置任务组成 。每个处理器按顺序运行,对传入的文档进行特定更改。处理器运行后,Elasticsearch 会将转换后的文档添加到您的数据流或索引中。
形象的理解就是在接受到请求到数据存入之间的一系列处理。

你可以使用它丰富你的数据

  • 可以将ip地址识别成地区后再储存
  • 将geo数据识别成省市区
  • 将产品id识别成产品详情
  • 等等...

官方提供了很多处理器。详情参考文档:https://www.elastic.co/guide/en/elasticsearch/reference/current/processors.html

聚合(Aggregations)

Elasticsearch 聚合使您能够构建复杂的数据摘要并深入了解关键指标、模式和趋势。
有点类似于 SQL 中的 group by 再加一些函数方法的操作,例如count、max等。
Elasticsearch 将聚合组织为三类:

  • Metric(度量),计算度量,例如求和,求平均值等
  • Bucket(桶),基于字段值、范围或其他标准将文档分组到桶中的聚合,简单来说就是分组。
  • Pipeline(管道),来自其他聚合。

集群(Cluster)

query(查询)和filter(过滤)的区别

  • 进行query的时候,返回结果的后面都会有一个_score字段表示这个结果的匹配程度,也就是相关性。类似MySQL的order;
  • 进行filter的时候,判断文档是否满足我们的筛选要求,不会计算任何的相关性。类似MySQL的where;
  • Elasticsearch的相似度计算默认使用TF-IDF算法;

Event Query Language (EQL)

事件查询语言 (EQL) 是一种用于基于事件的时间序列数据(例如日志、指标和跟踪)的查询语言。EQL 在 Elastic Security 中被广泛使用。

数据管理(Data Management)

在ES中的数据通常分为两类:

  • 内容(Content),可能会经常更新,但内容的价值会随着时间的推移保持相对稳定。
  • 时间序列数据(Time series data),会随着时间的推移不断积累,随着它的老化,它往往变得不那么重要,访问频率也越来越低。

为了帮助您管理数据,Elasticsearch 使您能够:

  • 定义具有不同性能特征的多层数据节点。
  • 使用索引生命周期管理(ILM)根据您的性能需求和保留策略自动转换数据层中的索引。
  • 利用存储在远程存储库中的可搜索快照为旧索引提供弹性,同时降低运营成本并保持搜索性能。
  • 对存储在性能较差的硬件上的数据 执行异步搜索。

mapping映射

映射(mapping)机制用于进行字段类型确认,将每个字段匹配为一种确定的数据类型。类似MySQL中的表结构定义
其主要作用:1、定义索引下的字段名,字段类型,倒排索引相关设置。

使用GET 索引名/_mapping可以查看此索引下的所有字段的映射。
或者使用GET 索引名/_mapping/字段名查看具体某个字段的映射。

mapping中的字段类型一旦设置,禁止直接修改,但可以增加(通过dynamic参数来控制新增)。

核心数据类型

字符串型:text、keyword(不会分词)
数值型:long、integer、short、byte、double、float、half_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(记录分词数)、murmur3(记录字符串hash值)

多字段特性

多字段特性(multi-fields),表示允许对同一字段采用不同的配置,比如分词。

字段类型:text

text类型的字段用来做全文检索,例如邮件的主题、淘宝京东中商品的描述等。这种字段在被索引存储前先进行分词,存储的是分词后的结果,而不是完整的字段。text字段不适合做排序和聚合。如果是一些结构化字段,分词后无意义的字段建议使用keyword类型,例如邮箱地址、主机名、商品标签等。

常有参数包含以下:

  • analyzer:用来分词,包含索引存储阶段搜索阶段(其中查询阶段可以被search_analyzer参数覆盖),该参数默认设置为index的analyzer设置或者standard analyzer;
  • index:是否可以被搜索到。默认是true
  • fields:Multi-fields允许同一个字符串值同时被不同的方式索引,例如用不同的analyzer使一个field用来排序和聚类,另一个同样的string用来分析和全文检索。下面会做详细的说明;
  • search_analyzer:这个字段用来指定搜索阶段时使用的分词器,默认使用analyzer的设置;
  • search_quote_analyzer:搜索遇到短语时使用的分词器,默认使用search_analyzer的设置;

字段类型:keyword

keyword用于索引结构化内容(例如电子邮件地址,主机名,状态代码,邮政编码或标签)的字段,这些字段被拆分后不具有意义,所以在es中应索引完整的字段,而不是分词后的结果。

通常用于过滤(例如在博客中根据发布状态来查询所有已发布文章),排序聚合。keyword只能按照字段精确搜索,例如根据文章id查询文章详情。如果想根据本字段进行全文检索相关词汇,可以使用text类型。

常有参数包含以下:

  • index:是否可以被搜索到。默认是true
  • fields:Multi-fields允许同一个字符串值同时被不同的方式索引,例如用不同的analyzer使一个field用来排序和聚类,另一个同样的string用来分析和全文检索。下面会做详细的说明
  • null_value:如果该字段为空,设置的默认值,默认为null
  • ignore_above:设置索引字段大小的阈值。该字段不会索引大小超过该属性设置的值,默认为2147483647,代表着可以接收任意大小的值。但是这一值可以被PUT Mapping Api中新设置的ignore_above来覆盖这一值。

字段类型:object

mapping中不用特意指定field为object类型,因为这是它的默认类型,因为整个es都是基于JSON。字段中还可以定义子字段。

PUT my_index/_doc/1
{ 
  "region": "US",
  "manager": { 
    "age":     30,
    "name": { 
      "first": "John",
      "last":  "Smith"
    }
  }
}

在es中会被按照以下形式进行索引:

{
  "region":             "US",
  "manager.age":        30,
  "manager.name.first": "John",
  "manager.name.last":  "Smith"
}

类型中的参数

参数参考官方文档 https://www.elastic.co/guide/en/elasticsearch/reference/current/mapping-params.html
以下这里只介绍几个比较常用的。

类型中的参数:analyzer参数

注意:仅test类型中才能使用。

类型中的参数:boost参数

在查询时,提升在相关度计算中的评分,默认值是1.0。当然在查询语句中使用boost也可以实现同样效果。

类型中的参数:copy_to参数

允许您将多个字段的值复制到一个组字段中,然后可以将该组字段作为单个字段进行查询。如果你经常搜索多个字段,可以将这些字段合并到一个字段,来提高查询速度。

类型中的参数:fields参数

为不同的目的以不同的方式索引同一字段时使用。例如一个字段可以同时全文检索和聚合或排序;

类型中的参数:index参数

作用是控制当前字段是否被索引,默认为true,false表示不记录,即不可被搜索。

类型中的参数:index_options参数

作用是用于控制倒排索引记录的内容。

类型中的参数:null_value参数

作用是当字段遇到null值的时候的处理策略,默认为null,即空值,此时es会忽略该值。可以通过这个参数设置某个字段的默认值。

mapping中的参数:dynamic参数

新字段允许自动添加。

Elasticsearch中mapping全解实战
查看其他更多关于_mapping相关内容

analyzer分析器

text类型的analyzer分析是非结构化的文本转化成一个结构化的格式,从而优化搜索。通常这个过程是分词
为了提高搜索准确性,除了在数据写入时转换词条,匹配Query查询语句时候也需要用相同的分析器对查询语句进行分析。

analyzer分析器组成:

  • Character Filters,字符过滤器,对原始文本进行折价、删除、转换,一个分析器可以有0个或多个过滤器。
  • Tokenizer,分词器,将文本分解成独立的tokens(通常是单词)并输出,分词器还会记录单词在文本中的位置与顺序,一个Analyzer 分析器有且只有 1个分词器
  • Token Filters,单词过滤(有些地方叫 词元过滤器、表征过滤、标记过滤等),可以增加、删除、修改单词,例如:转化小写、去停词、增加同义词等,当然单词过滤器不允许改版单词的位置或偏移量,一个分析器可以有多个单词过滤器。

分析器的处理流程:字符过滤器 -> 分词器 -> 单词过滤 -> 进入索引

当然,lasticsearch提供很多开箱即用的字符过滤器,分词器和单词过滤器。

text analysis文本分析发生在两个地方:

  • 给文档建立索引时,text类型的字段会进行文本分析;
  • 查询时,查询一个text字段时;

注意:在大多数情况下,应该使用相同的分析器在建立索引与查询,这样可以提高搜索准确率。

词干提取(stemming)是去除词缀得到词根的过程;词干分析器

如何选择/配置analyzer呢?

elasticsearch默认使用标准分析器,当标准分析器达不到我们要求时,可以使用其内置的其他分析器,内置分析器也不能满足我们要求可以自定义分析器;
那么怎么知道哪个具体分析器是否达到我们的要求呢?可以在工具中测试分析器,其语法如下:

POST _analyze
{
  "analyzer": "whitespace", // 分析器名称
  "filter":  [ "lowercase", "asciifolding" ], // 0个或多个过滤器
  "text":     "The quick brown fox." // 待测试的文本内容
}

内置分析器讲解

创建索引时,设置analysis.analyzer.default默认分析器,不指定默认使用standard analyzer标准分析器。
创建索引时,设置analysis.analyzer.default_search默认搜索时使用分析器。

  • Standard Analyzer(标准分析器)
  • Simple Analyzer(简单分析器)
  • Whitespace Analyzer(空格分析器)
  • Stop Analyzer(停止分析器)
  • Keyword Analyzer(关键词分析器)
  • Pattern Analyzer(正则分析器)
  • Language Analyzers(语言分析器)
  • Fingerprint Analyzer(指纹分析器)
  • 另外插件中还提供了很多分词器,例如:IK分词 pingyin分词 hanLP分词等

内置分词器

用于全文分词,分成一个个单词的分词器

  • Standard Tokenizer(标准分词器)
  • Letter Tokenizer
  • Lowercase Tokenizer
  • Whitespace Tokenizer
  • UAX URL Email Tokenizer
  • Classic Tokenizer
  • Thai Tokenizer

用于将文本或单词分成一小块的分词器

  • N-Gram Tokenizer
  • Edge N-Gram Tokenizer

用于结构化文本的分词器

  • Keyword Tokenizer
  • Pattern Tokenizer
  • Simple Pattern Tokenizer
  • Char Group Tokenizer
  • Simple Pattern Split Tokenizer
  • Path Tokenizer

内置单词过滤器

内置的单词过滤器比较多,参考官网给的信息
https://www.elastic.co/guide/en/elasticsearch/reference/current/analysis-tokenfilters.html

内置字符过滤器

  • HTML Strip Character Filter
  • Mapping Character Filter
  • Pattern Replace Character Filter

创建自定义分析器

自定义分析器可以由:0个或多个字符过滤器、1个分词器、0个或多个单词过滤器 自由组合完成。

自定义分析器,可以接收以下参数:

  • type参数,分析器类型,接受内置分析器类型,如果是自定义分析器使用custom或省略此参数;
  • tokenizer参数,内置的或自定义的分词器,必须;
  • char_filter参数,内置的或自定义的字符过滤器,可选;
  • filter参数,内置的或自定义的单词过滤器,可选
  • position_increment_gap参数

完整的自定义分析器例子

PUT my-index-000001
{
  "settings": {
    "analysis": {
      "analyzer": { // 自定义分析器
        "my_custom_analyzer": { // 自定义分析器名称
          "char_filter": [ // 自定义分析器里的,字符过滤器
            "emoticons" // 字符过滤器名
          ],
          "tokenizer": "punctuation", // 自定义分析器里的,分词器,punctuation是分词器名称
          "filter": [ // 自定义分析器里的,单词过滤器
            "lowercase", // 单词过滤器名称
            "english_stop"
          ]
        }
      },
      "tokenizer": { // 自定义分词器
        "punctuation": { // 自定义分析器名称
          "type": "pattern", // 自定义分词器使用了内置的分词器,正则分词器
          "pattern": "[ .,!?]" // 正则分词器的参数
        }
      },
      "char_filter": { // 自定义字符过滤器
        "emoticons": { // 自定义字符过滤器名称
          "type": "mapping", // 使用了内置的 mapping 字符过滤器
          "mappings": [ // mapping字符过滤器的参数
            ":) => _happy_",
            ":( => _sad_"
          ]
        }
      },
      "filter": { // 自定义单词过滤器
        "english_stop": { // 自定义单词过滤器名称
          "type": "stop", // 使用了内置的停词过滤器
          "stopwords": "_english_" // 停词过滤器的参数
        }
      }
    }
  }
}

POST my-index-000001/_analyze
{
  "analyzer": "my_custom_analyzer",
  "text": "I'm a :) person, and you?"
}

ElasticSearch DSL 语句使用

关键词讲解

增、删、改

查询

高级查询(配合业务需求)

Elasticsearch运维与集群相关

相关文章

此处评论已关闭