【个人技术经验及开发技巧分享】 【个人技术经验及开发技巧分享】
首页
  • 操作系统初识
  • JAVA基础
  • JVM
  • 开发框架
  • Redis
  • Zookeeper
  • 消息中间件
  • 持久化
  • 算法
  • 网络
  • 系统架构
  • 并发编程
  • 框架
  • 开发杂货
  • 线上排查
  • 技巧备忘
  • 部署指南
  • 版本管理
  • 工作流程
  • 发版流程
  • 友情链接
  • 网站备忘
  • 在线工具
  • 学习
  • 各种云
  • 应用下载

Louis

首页
  • 操作系统初识
  • JAVA基础
  • JVM
  • 开发框架
  • Redis
  • Zookeeper
  • 消息中间件
  • 持久化
  • 算法
  • 网络
  • 系统架构
  • 并发编程
  • 框架
  • 开发杂货
  • 线上排查
  • 技巧备忘
  • 部署指南
  • 版本管理
  • 工作流程
  • 发版流程
  • 友情链接
  • 网站备忘
  • 在线工具
  • 学习
  • 各种云
  • 应用下载
  • 操作系统初识

  • JAVA基础

  • JVM

  • 开发框架

  • Redis

  • Zookeeper

  • 消息中间件

  • 持久化

    • 数据库设计三大范式
    • 执行计划Explain
    • 索引
    • 事务
    • 数据库锁
    • MySQL数据同步
    • ElasticSearch基础
      • 1 核心概念
        • 1.1 索引 index
        • 1.2 映射 mapping
        • 1.3 字段Field
        • 1.4 字段类型 Type
        • 1.5 文档 document
        • 1.6 集群 cluster
        • 1.7 节点 node
        • 1.8 分片和副本 shards&replicas
      • 2 关于Index、Type、Document
        • 2.1 含义
        • 2.2 与MySQL类比
        • 2.3 Type废弃
      • 3 基本操作
        • 3.1 创建索引
        • 3.2 查询索引
        • 3.3 删除索引
        • 3.4 添加/修改文档
        • 3.5 删除文档
        • 3.6 批量查询操作
        • 3.7 批量增删改操作
      • 4 DSL语言高级查询
        • 4.1 无查询条件
        • 4.2 有查询条件
      • 5 聚合搜索
        • 5.1 bucket和metric
    • ElasticSearch杂记
  • 算法

  • 网络

  • 系统架构

  • 学习笔记
  • 持久化
luoxiaofeng
2022-04-28
目录

ElasticSearch基础

# 1 核心概念

# 1.1 索引 index

一个索引就是一个拥有几分相似特征的文档的集合。比如说,可以有一个客户数据的索引,另一个产品目录的索引,还有一个订单数据的索引。 一个索引由一个名字来标识(必须全部是小写字母的),并且当我们要对对应于这个索引中的文档进行索引、搜索、更新和删除的时候,都要使用到这个名字。

# 1.2 映射 mapping

ElasticSearch中的映射(Mapping)用来定义一个文档。类似数据库中的表结构定义。 mapping是处理数据的方式和规则方面做一些限制,如某个字段的数据类型、默认值、分词器、是否被索引等等,这些都是映射里面可以设置的。

# 1.3 字段Field

相当于是数据表的字段|列。

# 1.4 字段类型 Type

每一个字段都应该有一个对应的类型,例如:Text、Keyword、Byte等。

# 1.5 文档 document

一个文档是一个可被索引的基础信息单元,类似一条记录。文档以JSON (Javascript Object Notation)格式来表示。

# 1.6 集群 cluster

一个集群就是由一个或多个节点组织在一起,它们共同持有整个的数据,并一起提供索引和搜索功能。

# 1.7 节点 node

一个节点是集群中的一个服务器,作为集群的一部分,它存储数据,参与集群的索引和搜索功能。
一个节点可以通过配置集群名称的方式来加入一个指定的集群。默认情况下,每个节点都会被安排加入到一个叫做elasticsearch的集群中。

提示

这意味着,如果在网络中启动了若干个节点,并假定它们能够相互发现彼此,它们将会加入到一个叫做elasticsearch的集群中在一个集群里,可以拥有任意多个节点。 而且,如果当前网络中没有运行任何Elasticsearch节点,这时启动一个节点,会默认创建并加入一个叫 做elasticsearch的集群。

# 1.8 分片和副本 shards&replicas

分片
一个索引可以存储超出单个结点硬件限制的大量数据。

提示

比如,一个具有10亿文档的索引占据1TB的磁盘空间,而任一节点都没有这样大的磁盘空间; 或者单个节点处理搜索请求,响应太慢。

为了解决这个问题,Elasticsearch提供了将索引划分成多份的能力,这些份就叫做分片。
当创建一个索引的时候,可以指定你想要的分片的数量,每个分片本身也是一个功能完善并且独立的“索引”,这个“索引”可以被放置到集群中的任何节点上。
分片很重要,主要有两方面的原因 允许水平分割/扩展你的内容容量允许在分片之上进行分布式的、并行的操作,进而提高性能/吞吐量。 至于一个分片怎样分布,它的文档怎样聚合回搜索请求,是完全由Elasticsearch管理的,对于作为用户来说,这些都是透明的。

副本
在一个网络/云的环境里,失败随时都可能发生,在某个分片/节点不知怎么的就处于离线状态,或者由于任何原因消失了,这种情况下,有一个故障转移机制是非常有用并且是强烈推荐的。
为此目的,Elasticsearch允许你创建分片的一份或多份拷贝,这些拷贝叫做副本分片,或者直接叫副本。
副本之所以重要,有两个主要原因:

  1. 在分片/节点失败的情况下,提供了高可用性。 注意到复制分片从不与原/主要(original/primary)分片置于同一节点 上是非常重要的
  2. 扩展搜索量/吞吐量,因为搜索可以在所有的副本上并行运行 每个索引可以被分成多个分片。一个索引有0个或者多个副本 一旦设置了副本,每个索引就有了主分片和副本分片,分片和副本的数 量可以在索引创建的时候指定。在索引创建之后,可以在任何时候动态地改变副本的数量,但是不能改变分片的数量。

# 2 关于Index、Type、Document

# 2.1 含义

Index:索引。

Type:类型。

Document:文档。

文档是JSON类型的。

# 2.2 与MySQL类比

可以将 ES 中的这三个概念和 MySQL 类比

Index 对应 MySQL 中的 Database。

Type 对应 MySQL 中的 Table。

Document 对应 MySQL 中表的记录。

# 2.3 Type废弃

从ES 7.0 开始,Type 被废弃 在 7.0 以及之后的版本中 Type 被废弃了。

一个 index 中只有一个默认的 type,即 _doc。

ES 的 Type 被废弃后,库表合一,Index 既可以被认为对应 MySQL 的 Database,也可以认为对应 table。

也可以这样理解

ES 实例:对应 MySQL 实例中的一个 Database。

Index 对应 MySQL 中的 Table。

Document 对应 MySQL 中表的记录。

# 3 基本操作

# 3.1 创建索引

格式:PUT /索引名称

PUT /es_db
1

# 3.2 查询索引

格式:GET /索引名称

GET /es_db
1

# 3.3 删除索引

格式:DELETE /索引名称

DELETE /es_db
1

# 3.4 添加/修改文档

格式:PUT /索引名称/类型/id

PUT /es_db/_doc/1
{
 "name":"louis",
 "sex":1,
 "age":18,
 "address":"深圳", 
 "remark":"javadeveloper" 
}
1
2
3
4
5
6
7
8

提示

通过调用 PUT /es_db/_doc ,系统会自动生成 document id

使用HTTP PUT /es_db/_create/1 创建时,URL中显示指定 _create ,此时如果改 ID 的文档已经存在,操作失败

PUT /es_db/_create/1
{
 "name":"louis",
 "sex":1,
 "age":18,
 "address":"深圳", 
 "remark":"javadeveloper" 
}
1
2
3
4
5
6
7
8

# 3.5 删除文档

DELETE /es_db/_doc/1
1

# 3.6 批量查询操作

GET _mget 
{
  "docs": [
    {
      "_index": "es_db",
      "_type": "_doc",
      "_id": 1
    },
    {
      "_index": "es_db",
      "_type": "_doc",
      "_id": 2
    }
  ]
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

简化

GET /es_db/_doc/_mget 
{
  "docs": [
    {
      "_id": 1
    },
    {
      "_id": 2
    }
  ]
}
1
2
3
4
5
6
7
8
9
10
11

# 3.7 批量增删改操作

批量创建文档create

POST _bulk
{"create":{"_index":"es_db","_type":"_doc","_id":3}}
{"id":3,"title":"louis1","content":"louislouislouis1","tags":["java","es"]}
{"create":{"_index":"es_db","_type":"_doc","_id":4}}
{"id":4,"title":"louis2","content":"louislouislouis2","tags":["基础","es"]}
1
2
3
4
5

批量删除delete

POST _bulk
{"delete":{"_index":"es_db","_type":"_doc","_id":3}}
{"delete":{"_index":"es_db","_type":"_doc","_id":4}}
1
2
3

批量更新update

POST _bulk
{"update":{"_index":"es_db","_type":"_doc","_id":3}}
{"doc":{"content":"luo1"}}
{"update":{"_index":"es_db","_type":"_doc","_id":4}}
{"doc":{"content":"luo2"}}
1
2
3
4
5

# 4 DSL语言高级查询

提示

Domain Specific Language 领域专用语言

image-20220530172515939

# 4.1 无查询条件

无查询条件是查询所有,默认是查询所有的,或者使用match_all表示所有。

GET /es_db/_doc/_search
1
GET /es_db/_doc/_search
{
  "query": {
    "match_all": {}
  }
}
1
2
3
4
5
6

# 4.2 有查询条件

term 精确查询

POST /es_db/_doc/_search
{
  "query": {
    "term": {
      "name": "louis"
    }
  }
}
1
2
3
4
5
6
7
8

等同于

select * from student where name = 'louis'
1

match 模糊查询

POST /es_db/_doc/_search
{
  "from": 0,
  "size": 2,
  "query": {
    "match": {
      "name": "lou"
    }
  }
}
1
2
3
4
5
6
7
8
9
10

等同于

select * from user where name like '%lou%' limit 0, 2
1

multi_match 多字段模糊匹配查询与精准查询

POST /es_db/_doc/_search
{
  "query": {
    "multi_match": {
      "query": "lou",
      "fields": [
        "address",
        "name"
      ]
    }
  }
}
1
2
3
4
5
6
7
8
9
10
11
12

等同于

select * from student where name like '%lou%' or address like '%lou%' 
1

query_string 未指定字段条件查询 , 含 AND 与 OR 条件

POST /es_db/_doc/_search
{
  "query": {
    "query_string": {
      "query": "广州 OR 长沙"
    }
  }
}
1
2
3
4
5
6
7
8

query_string 指定字段条件查询 , 含 AND 与 OR 条件

POST /es_db/_doc/_search
{
  "query": {
    "query_string": {
      "query": "admin OR 长沙",
      "fields": [
        "name",
        "address"
      ]
    }
  }
}
1
2
3
4
5
6
7
8
9
10
11
12

范围查询

range 范围关键字

gte 大于等于

lte 小于等于

gt 大于

lt 小于

POST /es_db/_doc/_search
{
  "query": {
    "range": {
      "age": {
        "gte": 25,
        "lte": 28
      }
    }
  }
}
1
2
3
4
5
6
7
8
9
10
11

等同于

select * from user where age between 25 and 28
1

分页、输出字段、排序综合查询

POST /es_db/_doc/_search
{
  "query": {
    "range": {
      "age": {
        "gte": 25,
        "lte": 28
      }
    }
  },
  "from": 0,
  "size": 2,
  "_source": [
    "name",
    "age",
    "address"
  ],
  "sort": {
    "age": "desc"
  }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21

Filter过滤器方式查询

提示

它的查询不会计算相关性分值,也不会对结果进行排序, 因此效率会高一点,查询的结果可以被缓存。

POST /es_db/_doc/_search
{
  "query": {
    "bool": {
      "filter": {
        "term": {
          "age": 25
        }
      }
    }
  }
}
1
2
3
4
5
6
7
8
9
10
11
12

总结

1. match

模糊匹配,需要指定字段名,但是输入会进行分词,比如hello world会进行拆分为hello和world,然后匹配,如果字段中包含hello或者world,或者都包含的结果都会被查询出来,也就是说match是一个部分匹配的模糊查询。查询条件相对来说比较宽松。

2. term

这种查询和match在有些时候是等价的,比如我们查询单个的词hello,那么会和match查询结果一样,但是如果查询hello world,结果就相差很大,因为这个输入不会进行分词,就是说查询的时候,是查询字段分词结果中是否有hello world的字样,而不是查询字段中包含hello world的字样。当保存数据hello world时,elasticsearch会对字段内容进行分词,hello world会被分成hello和world,不存在hello world,因此这里的查询结果会为空。这也是term查询和match的区别。

3. match_phase

会对输入做分词,但是需要结果中也包含所有的分词,而且顺序要求一样。以hello world为例,要求结果中必须包含hello和world,而且还要求他们是连着的,顺序也是固定的,hello that world不满足,world hello也不满足条件。

4. query_string

和match类似,但是match需要指定字段名,query_string是所有字段搜索,范围更广泛。

# 5 聚合搜索

# 5.1 bucket和metric

bucket 就是一个聚合搜索时的数据分组。 如:

销售部门有员工张三和李四,开发部门有员工王五和赵六。那么根据部门分组聚合得到结果就是两个 bucket。

销售部门 bucket 中有张三和李四,开发部门 bucket 中有王五和赵六。

metric 就是对一个 bucket 数据执行的统计分析。如上述案例中,开发部门有2个员工,销售部门有2个员工,这就是 metric 。

metric 有多种统计,如:求和,最大值,最小值,平均值等。

示例

select count(*) from table group by column

group by column 分组后的每组数据就是 bucket 。 每个分组执行的 count(*) 就是 metric 。

GET /index_name/type_name/_search
{
"aggs" : {
"定义分组名称(最外层)": {
"分组策略如:terms、avg、sum" : {
"field" : "根据哪一个字段分组",
"其他参数" : ""
},
"aggs" : {
"分组名称1" : {},
"分组名称2" : {}
}
}
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

示例

size可以设置为0,表示不返回ES中的文档,只返回ES聚合之后的数据,提高查询速度,当然如果你需要这些文档的话,也可以按照实际情况进行设置

GET /cars/_search
{
  "size": 0,
  "aggs": {
    "group_by_color": {
      "terms": {
        "field": "color"
      },
      "aggs": {
        "group_by_brand": {
          "terms": {
            "field": "brand",
            "order": {
              "avg_by_price": "desc"
            }
          },
          "aggs": {
            "avg_by_price": {
              "avg": {
                "field": "price"
              }
            }
          }
        }
      }
    }
  }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28

先根据color聚合分组,在组内根据price再次聚合分组,这种操作可以称为下钻分析。

{
  "aggs": {
    "group_by_color": {
      "terms": {
        "field": "color",
        "order": {
          "avg_by_price_color": "asc"
        }
      },
      "aggs": {
        "avg_by_price_color": {
          "avg": {
            "field": "price"
          }
        },
        "group_by_brand": {
          "terms": {
            "field": "brand",
            "order": {
              "avg_by_price_brand": "desc"
            }
          },
          "aggs": {
            "avg_by_price_brand": {
              "avg": {
                "field": "price"
              }
            }
          }
        }
      }
    }
  }
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
#ES
MySQL数据同步
ElasticSearch杂记

← MySQL数据同步 ElasticSearch杂记→

最近更新
01
SpringBoot
10-21
02
Spring
10-20
03
Sentinel
10-14
更多文章>
Copyright © 2022-2023 Louis | 粤ICP备2022060093号-1
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式