ElasticSearch基本操作

8/5/2022 ElasticSearch

# 数据格式

Elasticsearch 是面向文档型数据库,一条数据在这里就是一个文档。我们可以把 Elasticsearch 里存储文档数据和关系型数据库 MySQL 存储数据的概念进行一个类比。 ES 里的 Index 可以看做一个库,而 Types 相当于表,Documents 则相当于表的行。

ElasticSearch

这里 Types 的概念已经被逐渐弱化,Elasticsearch 6.X 中,一个 index 下已经只能包含一个type,Elasticsearch 7.X 中, Type 的概念已经被删除了。

用 JSON 作为文档序列化的格式,比如一条用户信息:

{
 "name" : "John",
 "sex" : "Male",
 "age" : 25,
 "birthDate": "1990/05/01",
 "about" : "I love to go rock climbing",
 "interests": [ "sports", "music" ]
}

1
2
3
4
5
6
7
8
9

# HTTP 操作

  • 打开 kibanaDev Tools 菜单

# 索引操作

# 创建索引-PUT

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

  • PUT 索引名

    ElasticSearch

  • 发送请求后,服务器返回了这样的响应

{
  "acknowledged": true,  # true 操作成功
  "shards_acknowledged": true, # 分片操作成功
  "index": "user" # 索引名称
}
1
2
3
4
5
  • 如果重复添加索引呢?重复添加则会返回索引已经存在的错误信息

    ElasticSearch

# 查看全部索引-GET

  • GET _cat/indices?v

    ElasticSearch

  • _cat:表示查看的意思;

  • indices: 表示索引

  • health:当前服务器健康状态:green(集群完整)、yellow(单点正常、集群不完整)、red(单点不正常)

  • status:索引打开、关闭状态

  • index:索引名

  • uuid:索引统一编号

  • pri:主分片数量

  • rep:副本数量

  • docs.count:可用文档数量

  • docs.deleted:文档删除状态(逻辑删除)

  • store.size:主分片和副分片整体占空间大小

  • pri.store.size:主分片占空间大小

# 查看单个索引-GET

  • GET 索引名

    ElasticSearch

{
  "user"【索引名】: {
    "aliases"【别名】: {},
    "mappings"【映射】: {},
    "settings"【设置】: {
      "index"【设置 - 索引】: {
        "routing"【设置 - 索引路由】: {
          "allocation": {
            "include": {
              "_tier_preference": "data_content"
            }
          }
        },
        "number_of_shards"【设置 - 索引 - 主分片数量】: "1",
        "provided_name"【设置 - 索引 - 名称】: "user",
        "creation_date"【设置 - 索引 - 创建时间】: "1659678930693",
        "number_of_replicas"【设置 - 索引 - 副分片数量】: "1",
        "uuid"【设置 - 索引 - 唯一标识】: "P0pIpPyTSa-zS7kJCeE7Ng",
        "version"【设置 - 索引版本号】: {
          "created": "8030399"
        }
      }
    }
  }
}
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

# 删除索引-DELETE

  • delete 索引名

    ElasticSearch

# 文档操作

# 创建文档-POST

先创建好一个索引,接下来我们来创建文档,并添加数据。这里的文档可以类比为关系型数据库中的表数据,添加的数据格式为JSON格式

  • POST 索引名/_doc

    ElasticSearch

{
  "_index"【索引】: "user",
  "_id"【唯一标识,支持自定义】: "C1yqbIIBJVfoW_YKu2D5",
  "_version"【版本】: 1,
  "result"【结果】: "created",#这里的 create 表示创建成功
  "_shards"【分片】: {
    "total"【分片 - 总数】: 2,
    "successful"【分片 - 成功】: 1,
    "failed"【分片 - 失败】: 0
  },
  "_seq_no": 0,
  "_primary_term": 1
}
1
2
3
4
5
6
7
8
9
10
11
12
13
  • 自定义唯一标识:POST 索引名/_doc/(自定义ID)

# 查看文档-GET

  • 查看文档时,需要指明文档的唯一性标识,类似于 MySQL 中数据的主键查询
  • 查看指定文档:GET 索引名/_doc/(唯一标识)
  • 查看所有数据:GET 索引名/_search

    ElasticSearch

{
  "_index"【索引】: "user",
  "_id": "C1yqbIIBJVfoW_YKu2D5",
  "_version": 1,
  "_seq_no": 0,
  "_primary_term": 1,
  "found"【查询结果】: true,
  "_source"【文档源信息】: {
    "userName": "A佳技术",
    "age": "28"
  }
}
1
2
3
4
5
6
7
8
9
10
11
12

# 修改文档-POST

全局修改

  • POST 索引名/_doc/(唯一标识)

    ElasticSearch

{
  "_index": "user",
  "_id": "C1yqbIIBJVfoW_YKu2D5",
  "_version": 2,
  "result"【更新操作】: "updated",
  "_shards": {
    "total": 2,
    "successful": 1,
    "failed": 0
  },
  "_seq_no": 1,
  "_primary_term": 1
}
1
2
3
4
5
6
7
8
9
10
11
12
13

局部修改

局部修改需要注意一下,在8.x版本的语法变化

  • ES7.X版本中,局部修改语法是:POST 索引名/_updata/(唯一标识)
  • ES8.x版本中,局部修改语法如下图所示:

    ElasticSearch

ElasticSearch

# 删除文档-DELETE

  • 删除一个文档不会立即从磁盘上移除,它只是被标记成已删除(逻辑删除)
  • DELETE 索引名/_doc/(唯一标识)

    ElasticSearch

{
  "_index": "user",
  "_id": "C1yqbIIBJVfoW_YKu2D5",
  "_version"【版本:对数据的操作,都会更新版本】: 5,
  "result"【结果】: "deleted",# deleted 表示数据被标记为删除
  "_shards": {
    "total": 2,
    "successful": 1,
    "failed": 0
  },
  "_seq_no": 4,
  "_primary_term": 1
}
1
2
3
4
5
6
7
8
9
10
11
12
13

ElasticSearch

# 条件删除文档-POST

  • 首先分别增加多条数据,这里我添加了3条数据

    ElasticSearch

  • POST 索引名/_delete_by_query + 请求体条件

    ElasticSearch

{
  "took"【耗时】: 17,
  "timed_out"【是否超时】: false,
  "total"【总数】: 1,
  "deleted"【删除数量】: 1,
  "batches": 1,
  "version_conflicts": 0,
  "noops": 0,
  "retries": {
    "bulk": 0,
    "search": 0
  },
  "throttled_millis": 0,
  "requests_per_second": -1,
  "throttled_until_millis": 0,
  "failures": []
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
  • 查看文档数据情况,年龄20已经删除

    ElasticSearch

# 映射基本操作

# 原理

有了索引库,等于有了数据库中的 database

接下来就需要建索引库(index)中的映射了,类似于数据库(database)中的表结构(table)。创建数据库表需要设置字段名称,类型,长度,约束等;索引库也一样,需要知道这个类型下有哪些字段,每个字段有哪些约束信息,这就叫做映射(mapping)。

# 先创建索引-PUT

ElasticSearch

# 创建映射-PUT

  • PUT 索引名/_mapping + 请求体内容

    ElasticSearch

映射数据说明:

  • 字段名:任意填写

  • type:类型,Elasticsearch 中支持的数据类型非常丰富,说几个关键的:

    • String类型,又分两种

      • text:可分词,支持模糊查询,支持准确查询,不支持聚合查询
      • keyword:不可分词,数据会作为完整字段进行匹配,支持模糊查询,支持准确查询,支持聚合查询。
    • Numerical:数值类型,分两类

      • 基本数据类型:longintegershortbytedoublefloathalf_float
      • 浮点数的高精度类型:scaled_float
    • Date:日期类型

    • Array:数组类型

    • Object:对象

  • index:是否索引,默认为 true,也就是说你不进行任何配置,所有字段都会被索引。

    • true:字段会被索引,则可以用来进行搜索
    • false:字段不会被索引,不能用来搜索
  • store:是否将数据进行独立存储,默认为 false。

原始的文本会存储在_source 里面,默认情况下其他提取出来的字段都不是独立存储的,是从_source里面提取出来的。当然你也可以独立的存储某个字段,只要设置 "store": true 即可,获取独立存储的字段要比从 _source 中解析快得多,但是也会占用更多的空间,所以要根据实际业务需求来设置。

  • analyzer:分词器,这里的 ik_max_word 即使用 ik 分词器

# 查看映射-GET

  • GET 索引名/_mapping

    ElasticSearch

# 索引映射关联-PUT

  • 创建新的索引 student1,与之前的 student 进行映射关联
  • PUT student1 + 请求体
{
"settings": {},
"mappings": {
    "properties": {
        "name":{
            "type": "text",
            "index": true
        },
        "sex":{
            "type": "text",
            "index": false
        },
        "age":{
            "type": "long",
            "index": false
        }
    }
}
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

ElasticSearch