ElasticSearch-入门

1. 简介

  • ElasticSearch是⼀个开源,是⼀个基于Apache Lucene库构建的Restful搜索引擎. Elasticsearch是在Solr之后⼏年推出的
  • 提供了⼀个分布式,多租户能⼒的全⽂搜索引擎,具有HTTP Web界⾯(REST)和⽆架构JSON⽂档
  • Elasticsearch的官⽅客户端库提供Java,Groovy,PHP,Ruby,Perl,Python,.NET和Javascript。
  • 官网:https://www.elastic.co/cn/elasticsearch/

2. 单节点安装docker版

  1. 创建挂载目录并分配权限:
1
2
3
mkdir -p /home/dockerdata/elasticsearch/config
mkdir -p /home/dockerdata/elasticsearch/data
chmod 777 -R /home/dockerdata/elasticsearch
  1. 修改配置文件,让ES可以对外访问
1
echo "http.host: 0.0.0.0" >> /home/dockerdata/elasticsearch/config/elasticsearch.yml
  1. 启动应用
1
2
3
4
5
6
docker run -d --name elasticsearch --privileged=true -p 9200:9200 -p 9300:9300 \
-e "discovery.type=single-node" \
-e ES_JAVA_OPTS="-Xms1024m -Xmx1024m" \
-v /home/dockerdata/elasticsearch/config/elasticsearch.yml:/usr/share/elasticsearch/config/elasticsearch.yml \
-v /home/dockerdata/elasticsearch/data:/usr/share/elasticsearch/data \
-v /home/dockerdata/elasticsearch/plugins:/usr/share/elasticsearch/plugins elasticsearch:7.16.2
  • 9200是HTTP访问接口,9300是内部TCP通信端口
  • discovery.type=single-node表示单节点运行
  • ES_JAVA_OPTS="-Xms1024m -Xmx1024m"设置内存大小
  1. 验证是否启动

    在浏览器输入http://192.168.80.128:9200/ (IP根据环境更换),看到类似如下返回内容表示成功

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
{
"name" : "eece1579f720",
"cluster_name" : "elasticsearch",
"cluster_uuid" : "-WJ6WjtMQpGG10HlGUrC-w",
"version" : {
"number" : "7.16.2",
"build_flavor" : "default",
"build_type" : "docker",
"build_hash" : "2b937c44140b6559905130a8650c64dbd0879cfb",
"build_date" : "2021-12-18T19:42:46.604893745Z",
"build_snapshot" : false,
"lucene_version" : "8.10.1",
"minimum_wire_compatibility_version" : "6.8.0",
"minimum_index_compatibility_version" : "6.0.0-beta1"
},
"tagline" : "You Know, for Search"
}

3. 基本概念

ES类似于一个数据库,在数据库操作中有,库,表,表结构,字段,数据

3.1 索引(index)

索引可以类比成数据库的库

3.1.1 新增索引

新增一个aacopy的索引,为ES服务地址:http://192.168.80.128:9200/

  • 请求方式:PUT

  • 请求接口:{{es_server}}/aacopy

  • 响应结果:

    1
    2
    3
    4
    5
    {
    "acknowledged": true,
    "shards_acknowledged": true,
    "index": "aacopy"
    }

3.1.2 获取索引

获取索引名为aacopy的索引信息

  • 请求方式:GET

  • 请求接口:{{es_server}}/aacopy

  • 响应结果:

    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
    {
    "aacopy": {
    "aliases": {},
    "mappings": {},
    "settings": {
    "index": {
    "routing": {
    "allocation": {
    "include": {
    "_tier_preference": "data_content"
    }
    }
    },
    "number_of_shards": "1",
    "provided_name": "aacopy",
    "creation_date": "1641403730051",
    "number_of_replicas": "1",
    "uuid": "18l1JVJBQKKZWS0BHob8Ag",
    "version": {
    "created": "7160299"
    }
    }
    }
    }
    }
    • aliases:索引别名
    • mappings:映射
    • settings:设置
    • index:索引
    • number_of_shards:主分片数量
    • number_of_replicas:副分片数量
    • uuid:索引唯一标识
    • version:索引版本
    • provided_name:索引名称
    • creation_date:索引创建时间

3.1.3 删除索引

删除索引名为aacopy的索引

  • 请求方式:DELETE

  • 请求接口:{{es_server}}/aacopy

  • 响应结果:

    1
    2
    3
    {
    "acknowledged": true
    }

3.1.4 获取多个索引

先创建两个索引,hello和aacopy,再同时获取这两个索引

  • 请求方式:GET

  • 请求接口:{{es_server}}/hello,aacopy

  • 响应结果:

    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
    {
    "aacopy": {
    "aliases": {},
    "mappings": {},
    "settings": {
    "index": {
    "routing": {
    "allocation": {
    "include": {
    "_tier_preference": "data_content"
    }
    }
    },
    "number_of_shards": "1",
    "provided_name": "aacopy",
    "creation_date": "1641404107223",
    "number_of_replicas": "1",
    "uuid": "5u-oJh8xSPivutUt6plnnA",
    "version": {
    "created": "7160299"
    }
    }
    }
    },
    "hello": {
    "aliases": {},
    "mappings": {},
    "settings": {
    "index": {
    "routing": {
    "allocation": {
    "include": {
    "_tier_preference": "data_content"
    }
    }
    },
    "number_of_shards": "1",
    "provided_name": "hello",
    "creation_date": "1641404112594",
    "number_of_replicas": "1",
    "uuid": "295E_bNYSgGcSmU_FvXB-g",
    "version": {
    "created": "7160299"
    }
    }
    }
    }
    }

3.1.5 获取所有索引

获取所有索引的索引信息

方式一

  • 请求方式:GET

  • 请求接口:{{es_server}}/_all

  • 响应结果:

    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
    {
    "aacopy": {
    "aliases": {},
    "mappings": {},
    "settings": {
    "index": {
    "routing": {
    "allocation": {
    "include": {
    "_tier_preference": "data_content"
    }
    }
    },
    "number_of_shards": "1",
    "provided_name": "aacopy",
    "creation_date": "1641404107223",
    "number_of_replicas": "1",
    "uuid": "5u-oJh8xSPivutUt6plnnA",
    "version": {
    "created": "7160299"
    }
    }
    }
    },
    "hello": {
    "aliases": {},
    "mappings": {},
    "settings": {
    "index": {
    "routing": {
    "allocation": {
    "include": {
    "_tier_preference": "data_content"
    }
    }
    },
    "number_of_shards": "1",
    "provided_name": "hello",
    "creation_date": "1641404112594",
    "number_of_replicas": "1",
    "uuid": "295E_bNYSgGcSmU_FvXB-g",
    "version": {
    "created": "7160299"
    }
    }
    }
    }
    }

方式二

  • 请求方式:GET

  • 请求接口:{{es_server}}/_cat/indices?v

  • 响应结果:

    1
    2
    3
    4
    health status index            uuid                   pri rep docs.count docs.deleted store.size pri.store.size
    green open .geoip_databases XpWGyzoNQFKMixWiBt-Ffg 1 0 44 0 40.8mb 40.8mb
    yellow open hello 295E_bNYSgGcSmU_FvXB-g 1 1 0 0 226b 226b
    yellow open aacopy 5u-oJh8xSPivutUt6plnnA 1 1 0 0 226b 226b
    • health:服务器健康状态,green(集群完整) yellow(单点正常、集群不完整) red(单点不正常)
    • status:索引打开、关闭状态
    • index:索引名
    • uuid:索引统一编号
    • pri:主分片数量
    • rep:副本数量
    • docs.count:可用文档数量
    • docs.deleted:文档删除状态(逻辑删除)
    • store.size:主分片和副分片整体占空间大小
    • pri.store.size:主分片占空间大小

3.1.6 索引是否存在

判断是否存在索引名为aacopy的索引

  • 请求方式:HEAD
  • 请求接口:{{es_server}}/aacopy
  • 响应结果:如果存在Status为200,如果不存在Status为404

3.1.7 关闭索引

关闭名为aacopy的索引

  • 请求方式:POST

  • 请求接口:{{es_server}}/aacopy/_close

  • 响应结果:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    {
    "acknowledged": true,
    "shards_acknowledged": true,
    "indices": {
    "aacopy": {
    "closed": true
    }
    }
    }

3.1.8 打开索引

打开名为aacopy的索引

  • 请求方式:POST

  • 请求接口:{{es_server}}/aacopy/_open

  • 响应结果:

    1
    2
    3
    4
    {
    "acknowledged": true,
    "shards_acknowledged": true
    }

3.2 类型(type)

7.X版本已废弃,type可以类比成数据库的表

3.3 映射(mapping)

映射可以类比成数据库的表结构

3.3.1 新增映射

为ES服务地址:http://192.168.80.128:9200/
  • 请求方式:PUT

  • 请求接口:{{es_server}}/aacopy/_mapping

  • Content-Type:application/json

  • 请求参数:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    {
    "properties": {
    "name": {
    "type": "text"
    },
    "tags": {
    "type": "keyword"
    }
    }
    }
  • 响应结果:

    1
    2
    3
    {
    "acknowledged": true
    }

映射数据说明:

  • 字段名:任意填写,下面指定许多属性,例如:name,tags
  • type:类型
    • String:类型
      • text:可分词
      • keyword:不可分词,数据会作为完整字段进行匹配
    • Numerical:数值类型
      • 基本数据类型:long、integer、short、byte、double、float、half_float
      • 浮点数的高精度类型:scaled_float
    • Date:日期类型
    • Array:数组类型
    • Object:对象
  • index:是否索引,默认为 true,所有字段都会被索引
    • true:字段会被索引,则可以用来进行搜索
    • false:字段不会被索引,不能用来搜索
  • store:是否将数据进行独立存储,默认为 false
    • 原始的文本会存储在_source 里面,默认情况下其他提取出来的字段都不是独立存储的,是从_source 里面提取出来的。当然你也可以独立的存储某个字段,只要设置”store”: true 即可,获取独立存储的字段要比从_source 中解析快得多,但是也会占用更多的空间,所以要根据实际业务需求来设置。
  • analyzer:分词器

3.3.2 查看映射

  • 请求方式:GET

  • 请求接口:{{es_server}}/aacopy/_mapping

  • 响应结果:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    {
    "aacopy": {
    "mappings": {
    "properties": {
    "name": {
    "type": "text"
    },
    "tags": {
    "type": "keyword"
    }
    }
    }
    }
    }

3.3.3 查看多个索引的映射

查看aacopy和hello两个索引的映射

  • 请求方式:GET

  • 请求接口:{{es_server}}/aacopy,hello/_mapping

  • 响应结果:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    {
    "hello": {
    "mappings": {}
    },
    "aacopy": {
    "mappings": {
    "properties": {
    "name": {
    "type": "text"
    },
    "tags": {
    "type": "keyword"
    }
    }
    }
    }
    }

3.3.4 查看所有索引的映射

  • 请求方式:GET

  • 请求接口:

    • {{es_server}}/_mapping
    • {{es_server}}/_all/_mapping
  • 响应结果:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    {
    "hello": {
    "mappings": {}
    },
    "aacopy": {
    "mappings": {
    "properties": {
    "name": {
    "type": "text"
    },
    "tags": {
    "type": "keyword"
    }
    }
    }
    }
    }

3.3.5 增加映射字段

新增一个description的字段

  • 请求方式:PUT

  • 请求接口:{{es_server}}/aacopy/_mapping

  • Content-Type:application/json

  • 请求参数:

    1
    2
    3
    4
    5
    6
    7
    {
    "properties": {
    "description": {
    "type": "text"
    }
    }
    }
  • 响应结果:

    1
    2
    3
    {
    "acknowledged": true
    }

3.4 字段(field)

对应数据库的字段

3.5 文档(document)

对应数据库中的一行记录

3.5.1 新增文档

为ES服务地址:http://192.168.80.128:9200/

在aacopy索引中新增自定id为1的文档,如果不指定id,ES也会自动生产一个id

  • 请求方式:PUT

  • 请求接口:{{es_server}}/aacopy/_doc/1

    接口可以添加参数?op_type=create,指定为新增,防止修改已存在的数据

  • Content-Type:application/json

  • 请求参数:

    1
    2
    3
    4
    {
    "name":"小明",
    "tags":"A"
    }
  • 响应结果:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    {
    "_index": "aacopy",
    "_type": "_doc",
    "_id": "1",
    "_version": 1,
    "result": "created",
    "_shards": {
    "total": 2,
    "successful": 1,
    "failed": 0
    },
    "_seq_no": 0,
    "_primary_term": 7
    }

3.5.2 查看文档

单个文档

查看aacopy索引中id为1的文档

  • 请求方式:GET

  • 请求接口:{{es_server}}/aacopy/_doc/1

  • 响应结果:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    {
    "_index": "aacopy",
    "_type": "_doc",
    "_id": "1",
    "_version": 1,
    "_seq_no": 0,
    "_primary_term": 7,
    "found": true,
    "_source": {
    "name": "小明",
    "tags": "A"
    }
    }

多个文档

在aacopy索引中新增自定id为1和2两个文档,再查出来

方式一:

  • 请求方式:GET/POST

  • 请求接口:{{es_server}}/_mget

  • Content-Type:application/json

  • 请求参数:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    {
    "docs": [
    {
    "_index": "aacopy",
    "_id": "1"
    },
    {
    "_index": "aacopy",
    "_id": "2"
    }
    ]
    }
  • 响应结果:

    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
    {
    "docs": [
    {
    "_index": "aacopy",
    "_type": "_doc",
    "_id": "1",
    "_version": 1,
    "_seq_no": 0,
    "_primary_term": 7,
    "found": true,
    "_source": {
    "name": "小明",
    "tags": "A"
    }
    },
    {
    "_index": "aacopy",
    "_type": "_doc",
    "_id": "2",
    "_version": 1,
    "_seq_no": 1,
    "_primary_term": 7,
    "found": true,
    "_source": {
    "name": "张三",
    "tags": "三三三"
    }
    }
    ]
    }

方式二:

  • 请求方式:GET/POST

  • 请求接口:{{es_server}}/aacopy/_doc/_mget

  • Content-Type:application/json

  • 请求参数:

    1
    2
    3
    {
    "ids": ["1", "2"]
    }
  • 响应结果:同方式一

3.5.3 更新文档

3.5.3.1 更新数据
  • 请求方式:POST

  • 请求接口:{{es_server}}/aacopy/_update/1

  • Content-Type:application/json

  • 请求参数:

    1
    2
    3
    4
    5
    {
    "doc": {
    "tags": "AA"
    }
    }
  • 响应结果:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    {
    "_index": "aacopy",
    "_type": "_doc",
    "_id": "1",
    "_version": 2,
    "result": "updated",
    "_shards": {
    "total": 2,
    "successful": 1,
    "failed": 0
    },
    "_seq_no": 3,
    "_primary_term": 8
    }
3.5.3.2 新增字段
  • 请求方式:POST

  • 请求接口:{{es_server}}/aacopy/_update/1

  • Content-Type:application/json

  • 请求参数:

    1
    2
    3
    {
    "script": "ctx._source.age = 18"
    }
  • 响应结果:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    {
    "_index": "aacopy",
    "_type": "_doc",
    "_id": "1",
    "_version": 3,
    "result": "updated",
    "_shards": {
    "total": 2,
    "successful": 1,
    "failed": 0
    },
    "_seq_no": 4,
    "_primary_term": 8
    }
3.5.3.3 删除字段

请求方式和接口与新增字段相同,参数不同

  • 请求参数:

    1
    2
    3
    {
    "script": "ctx._source.remove(\"age\")"
    }
3.5.3.4 传递参数更新文档

请求方式和接口与新增字段相同,参数不同

  • 请求参数:

    1
    2
    3
    4
    5
    6
    7
    8
    {
    "script": {
    "source": "ctx._source.tags += params.tags",
    "params": {
    "tags": "S"
    }
    }
    }
3.5.3.5 upsert

如果执行更新的文档不存在,则创建文档,并设置upsert中的初始值,如果文档存在,则执行script中的更新操作

更新id为3的这个不存在的文档

  • 请求接口:{{es_server}}/aacopy/_update/3

  • 请求参数

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    {
    "script": {
    "source": "ctx._source.num += params.num",
    "params": {
    "num": 10
    }
    },
    "upsert": {
    "num": 1
    }
    }

3.5.4 删除文档

  • 请求方式:DELETE

  • 请求接口:{{es_server}}/aacopy/_doc/3

  • 响应结果:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    {
    "_index": "aacopy",
    "_type": "_doc",
    "_id": "3",
    "_version": 3,
    "result": "deleted",
    "_shards": {
    "total": 2,
    "successful": 1,
    "failed": 0
    },
    "_seq_no": 9,
    "_primary_term": 8
    }

3.6 分片(shard)

分片分为主分片和副本分片,一个索引数据分布在多个主分片上,每个主分片有多个副本,是主分片的备份