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运维与集群相关
最后更新于 2021-11-22 01:19:37 并被添加「Elasticsearch教程」标签,已有 1017 位童鞋阅读过。
本站使用「署名 4.0 国际」创作共享协议,可自由转载、引用,但需署名作者且注明文章出处
此处评论已关闭