ElasticSearch

笔记学习视频:【尚硅谷】ElasticSearch教程入门到精通(基于ELK技术栈elasticsearch 7.x+8.x新特性)_哔哩哔哩_bilibili

ElasticSearch官网:Elasticsearch:官方分布式搜索和分析引擎 | Elastic

简介

The Elastic Stack, 包括 Elasticsearch、Kibana、Beats和Logstash(也称为 ELK Stack)。能够安全可靠地获取任何来源、任何格式的数据,然后实时地对数据进行搜索、分析和可视化。Elaticsearch,简称为ES,ES是一个开源的高扩展的分布式全文搜索引擎,是整个Elastic Stack技术栈的核心。它可以近乎实时的存储、检索数据;本身扩展性很好,可以扩展到上百台服务器,处理 PB 级别的数据。

Elasticsearch 是面向文档型数据库,一条数据在这里就是一个文档。这里和MySQL进行对比。

ES 里的 Index 可以看做一个库,而Type相当于表,Documents则相当于表的行。 这里Type的概念已经被逐渐弱化,Elasticsearch 6.X 中,一个 index 下已经只能包含一个 type,Elasticsearch 7.X 中, Type 的概念已经被删除了。文档是用JSON作为序列化的格式

安装

各版本官方下载地址:Past Releases of Elastic Stack Software | Elastic

7.17.9版本官方下载地址:Elasticsearch 7.17.9 | Elastic

下载相对应系统版本的ES,这里使用的是Windows。

目录结构如下:

1
2
3
4
5
6
7
8
9
ElasticSearch-7.17.9
├─bin -可执行脚本
├─config -配置目录
├─data -数据目录
├─jdk -内置JDK目录
├─lib -类库
├─logs -日志目录
├─modules -模块目录
└─plugins -插件目录

解压后在bin下双击elasticsearch.bat启动

启动后访问http://localhost:9200 出现类似如下信息表示成功:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
{
"name": "LAPTOP-xxx",
"cluster_name": "elasticsearch",
"cluster_uuid": "V5Ep9BM7Q2q9WCGBOYQ2BQ",
"version": {
"number": "7.17.9",
"build_flavor": "default",
"build_type": "zip",
"build_hash": "ef48222227ee6b9e70e502f0f0daa52435ee634d",
"build_date": "2023-01-31T05:34:43.305517834Z",
"build_snapshot": false,
"lucene_version": "8.11.1",
"minimum_wire_compatibility_version": "6.8.0",
"minimum_index_compatibility_version": "6.0.0-beta1"
},
"tagline": "You Know, for Search"
}

注意:9300 端口为 Elasticsearch 集群间组件的通信端口,9200 端口为浏览器访问的 http 协议 RESTful 端口。

出现问题

  1. Elasticsearch是使用java开发的,且7.8版本的ES需要JDK版本1.8以上,默认安装包带有 jdk 环境,如果系统配置 JAVA_HOME,那么使用系统默认的 JDK,如果没有配置使用自带的 JDK,一般建议使用系统配置的 JDK。

  2. 双击启动窗口闪退,通过路径访问追踪错误,如果是“空间不足”,请修改config/jvm.options配置文件

    1
    2
    3
    4
    5
    6
    # 设置 JVM 初始内存为 1G。此值可以设置与-Xmx 相同,以避免每次垃圾回收完成后 JVM 重新分配内存
    # Xms represents the initial size of total heap space
    # 设置 JVM 最大可用内存为 1G
    # Xmx represents the maximum size of total heap space
    -Xms1g
    -Xmx1g

ES基本操作

HTTP操作

可以使用Postman来请求Http

HTTP请求ES使用的是RESTful

RESTful 架构详解 | 菜鸟教程 (runoob.com)

索引操作

创建索引

对比关系型数据库,创建索引就等同于创建数据库。

1
PUT | http://127.0.0.1:9200/shopping

创建索引名为shopping的索引

成功后返回:

1
2
3
4
5
6
7
8
{
// 响应结果
"acknowledged": true,
// 分片结果
"shards_acknowledged": true,
// 索引名称
"index": "shopping"
}

注意:创建索引库的分片数默认 1 片,在 7.0.0 之前的 Elasticsearch 版本中,默认 5 片

PUT具有幂等性,重复添加会返回错误信息,如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
{
"error": {
"root_cause": [
{
"type": "resource_already_exists_exception",
"reason": "index [shopping/GWBeiEYFTZesYHgCPgvRMw] already exists",
"index_uuid": "GWBeiEYFTZesYHgCPgvRMw",
"index": "shopping"
}
],
"type": "resource_already_exists_exception",
"reason": "index [shopping/GWBeiEYFTZesYHgCPgvRMw] already exists",
"index_uuid": "GWBeiEYFTZesYHgCPgvRMw",
"index": "shopping"
},
"status": 400
}

注意:每次添加的索引uuid都不一样,由ES自动生成

查看所有索引
1
GET | http://127.0.0.1:9200/_cat/indices?v
  • _cat:查看

  • indices:索引

类似于MySQL的show tables;

结果如下:

1
2
3
4
health status index            uuid                   pri rep docs.count docs.deleted store.size pri.store.size
green open .geoip_databases C0Hb6jtCSAKTujBNW90M2g 1 0 42 0 40.6mb 40.6mb
yellow open shopping GWBeiEYFTZesYHgCPgvRMw 1 1 0 0 226b 226b
yellow open shopping1 Dr-xHmbwTA2icb-Yn_65EQ 1 1 0 0 226b 226b

整理成表格:

health status index uuid pri rep docs.count docs.deleted store.size pri.store.size
green open .geoip_databases C0Hb6jtCSAKTujBNW90M2g 1 0 42 0 40.6mb 40.6mb
yellow open shopping GWBeiEYFTZesYHgCPgvRMw 1 1 0 0 226b 226b
yellow open shopping1 Dr-xHmbwTA2icb-Yn_65EQ 1 1 0 0 226b 226b

表头含义:

  • health:当前服务器健康状态
    • green:集群完整
    • yellow:单点正常、集群不完整
    • red:单点不正常
  • status:索引状态,open和close
  • index:索引名
  • uuid:索引统一编号
  • pri:主分片数量
  • rep:副本数量
  • docs.count:可用文档数量
  • docs.deleted:文档删除状态(逻辑删除)
  • store.size:主分片和副分片整体占空间大小
  • pri.store.size:主分片占空间大小
查看单个索引
1
GET | http://127.0.0.1:9200/shopping

查询结果如下:

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
{
// 索引名
"shopping": {
// 别名
"aliases": {},
// 映射
"mappings": {},
// 设置
"settings": {
"index": {
"routing": {
"allocation": {
"include": {
"_tier_preference": "data_content"
}
}
},
// 主分片数量
"number_of_shards": "1",
"provided_name": "shopping",
// 创建索引的时间戳
"creation_date": "1678613828568",
// 副分片数量
"number_of_replicas": "1",
"uuid": "GWBeiEYFTZesYHgCPgvRMw",
"version": {
"created": "7170999"
}
}
}
}
}
删除索引
1
DELETE | http://127.0.0.1:9200/shopping

删除成功,返回结果如下:

1
2
3
{
"acknowledged": true
}

删除失败,返回错误信息如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
{
"error": {
"root_cause": [
{
"type": "index_not_found_exception",
"reason": "no such index [shopping]",
"resource.type": "index_or_alias",
"resource.id": "shopping",
"index_uuid": "_na_",
"index": "shopping"
}
],
"type": "index_not_found_exception",
"reason": "no such index [shopping]",
"resource.type": "index_or_alias",
"resource.id": "shopping",
"index_uuid": "_na_",
"index": "shopping"
},
"status": 404
}

文档操作

跟MySQL相比,索引相当于数据库,而文档相当于

创建文档
1
2
3
4
5
6
7
8
POST | http://127.0.0.1:9200/shopping/_doc
请求体:
{
"title":"小米13",
"category":"小米",
"images":"https://cdn.cnbj1.fds.api.mi-img.com/product-images/xiaomi-13kb7buy/4301.png",
"price":3999.00
}

_doc表示对索引shopping进行文档操作
创建成功,返回结果如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
{
"_index": "shopping",
"_type": "_doc",
// 文档的唯一标识,类比MySQL的主键
"_id": "o1my1YYBHspLkJUmUbdQ",
// 版本号,每次操作都会更新
"_version": 1,
// 这里created表示创建成功
"result": "created",
// 分片
"_shards": {
"total": 2,
"successful": 1,
"failed": 0
},
"_seq_no": 0,
"_primary_term": 1
}

注意:每次添加的id都不一样,由ES自动生成

在创建文档时指定id为1001,如下:

1
POST | http://127.0.0.1:9200/shopping/_doc/1001

此处需要注意:如果增加数据时明确数据主键,那么请求方式也可以为 PUT

查看所有文档

查询索引shopping的全部文档

1
GET | http://127.0.0.1:9200/shopping/_search

查询成功结果如下:

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
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
{
"took": 12,
"timed_out": false,
// 分片
"_shards": {
"total": 1,
"successful": 1,
"skipped": 0,
"failed": 0
},
// 命中
"hits": {
"total": {
// 查询到的数量
"value": 3,
"relation": "eq"
},
"max_score": 1.0,
// 查询到的数据
"hits": [
{
"_index": "shopping",
"_type": "_doc",
"_id": "o1my1YYBHspLkJUmUbdQ",
"_score": 1.0,
"_source": {
"title": "小米13",
"category": "小米",
"images": "https://cdn.cnbj1.fds.api.mi-img.com/product-images/xiaomi-13kb7buy/4301.png",
"price": 3999.00
}
},
{
"_index": "shopping",
"_type": "_doc",
"_id": "plm51YYBHspLkJUmxrdq",
"_score": 1.0,
"_source": {
"title": "小米13",
"category": "小米",
"images": "https://cdn.cnbj1.fds.api.mi-img.com/product-images/xiaomi-13kb7buy/4301.png",
"price": 3999.00
}
},
{
"_index": "shopping",
"_type": "_doc",
"_id": "1001",
"_score": 1.0,
"_source": {
"title": "小米13",
"category": "小米",
"images": "https://cdn.cnbj1.fds.api.mi-img.com/product-images/xiaomi-13kb7buy/4301.png",
"price": 3999.00
}
}
]
}
}
查看单个文档
1
GET | http://127.0.0.1:9200/shopping/_doc/1001

查询索引shopping文档id为1001的数据,如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
{
"_index": "shopping",
"_type": "_doc",
"_id": "1001",
"_version": 1,
"_seq_no": 2,
"_primary_term": 1,
// 是否查询到结果
"found": true,
// 文档源信息
"_source": {
"title": "小米13",
"category": "小米",
"images": "https://cdn.cnbj1.fds.api.mi-img.com/product-images/xiaomi-13kb7buy/4301.png",
"price": 3999.00
}
}
修改文档

文档信息覆盖:

1
2
3
4
5
6
7
8
POST | http://127.0.0.1:9200/shopping/_doc/1001
请求体:
{
"title":"小米13Pro",
"category":"小米",
"images":"https://cdn.cnbj1.fds.api.mi-img.com/product-images/xiaomi13pro5r9luc/specs/4025.png",
"price":5399.00
}

覆盖成功,返回结果如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
{
"_index": "shopping",
"_type": "_doc",
"_id": "1001",
// 版本
"_version": 2,
// updated表示更新成功
"result": "updated",
"_shards": {
"total": 2,
"successful": 1,
"failed": 0
},
"_seq_no": 3,
"_primary_term": 1
}

修改部分信息:_doc —> _update

1
2
3
4
5
6
7
POST | http://127.0.0.1:9200/shopping/_update/1001
请求体:
{
"doc": {
"price":6299.00
}
}

只修改价格,返回修改成功结果的结构同上。

删除文档
1
DELETE | http://127.0.0.1:9200/shopping/_doc/1001

删除索引shopping文档id为1001,返回成功结果:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
{
"_index": "shopping",
"_type": "_doc",
"_id": "1001",
"_version": 4,
// deleted表示删除成功
"result": "deleted",
"_shards": {
"total": 2,
"successful": 1,
"failed": 0
},
"_seq_no": 5,
"_primary_term": 1
}
条件查询

在请求路径上带参数的条件查询

1
GET | http://127.0.0.1:9200/shopping/_search?q=category:小米

但是容易出现中文乱码,所以可以在请求体里来带参:

1
2
3
4
5
6
7
8
9
GET | http://127.0.0.1:9200/shopping/_search
请求体:
{
"query": {
"match": {
"category": "小米"
}
}
}

推荐使用第二种查询方式

若要对查询的数据进行字段过滤(例如过滤title),可以在请求体添加参数:

1
"_source": ["title"]
分页查询
1
2
3
4
5
6
7
8
9
10
11
12
13
14
GET | http://127.0.0.1:9200/shopping/_search
请求体:
{
"query": {
// 表示全查询
"match_all": {
}
},
// 当前页数据起始的索引位置
// 第n页数据起始的索引=(n - 1) * size
"from": 0,
// 每一页显示多少个数据
"size": 2
}

若要对查询结果进行排序,可以在请求体添加如下参数:

1
2
3
4
5
6
7
"sort": {
// 表示对price字段排序
"price": {
// desc是降序,asc是升序
"order": "desc"
}
}
多条件查询
1
GET | http://127.0.0.1:9200/shopping/_search

AND 下面请求体表示查询category为小米和价格为4999.00的数据

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
{
"query": {
// 表示多条件查询
"bool": {
// 表示and
"must": [{
"match": {
"category": "小米"
}
},{
"match": {
"price": "3999.00"
}
}]
}
}
}

OR 下面请求体表示查询category为小米或华为的数据

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
{
"query": {
// 表示多条件查询
"bool": {
// 表示or
"should": [{
"match": {
"category": "小米"
}
},{
"match": {
"category": "华为"
}
}]
}
}
}

如果我们要表示price>2000的话可以这样表示:

1
2
3
4
5
6
7
8
9
10
11
//在bool内添加:
"filter": {
// 表示范围
"range": {
"price": {
// gt = greater than 大于
// lt = less than 小于
"gt": 2000
}
}
}
全文检索&高亮查询
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
GET | http://127.0.0.1:9200/shopping/_search
请求体:
{
"query": {
// 使用match是 拆分字词后的模糊查询
"match": {
// 下列是查询包含“米”的数据
"category": "米"
// 下列查询包含"小"或"华"的数据
// "category": "小华"
}
// 若使用的是match_parse,则表示 整体匹配的模糊查询
},
// 高亮查询,高亮指定字段
"highlight": {
"fields": {
// 高亮显示category字段 相应关键词
"category": {}
}
}
}
聚合查询
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
GET | http://127.0.0.1:9200/shopping/_search
请求体:
{
// 聚合操作
"aggs": {
// 名称,可以随意取
"price_group": {
// terms分组,类似于mysql的group by
// 类似的操作还有 avg max min sum doc_count
"terms": {
// 分组的字段,这里是按price的不同来分组
"field": "price"
}
}
},
// 查询显示的数量
"size": 0
}
映射关系

获取索引shopping的映射信息

1
GET | http://127.0.0.1:9200/shopping/_mapping

创建索引shopping的映射信息

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
PUT | http://127.0.0.1:9200/shopping/_mapping
请求体:
{
"properties": {
// 配置字段的映射关系
"category": {
// 字段类型
"type": "text",
// 是否可以索引查询
"index": true
},
"price": {
"type": "keyword",
// 若为false则不能被全文检索
"index": false
}
}
}