使用者通过请求restful url 与ElasticSearch进行交互

这里使用curl命令行工具进行请求的收发,除此之外,使用任意http请求库也可

推荐一款curl生成工具:curl请求在线生成-小工具在线(xgjzx.cn)

查看ElasticSearch的基本信息

请求方式:get

请求url: 协议://主机:端口

1
curl -X GET http://localhost:9200

响应

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
{
"name" : "XIAOXINPRO16",
"cluster_name" : "elasticsearch",
"cluster_uuid" : "SceOScDoQVeTevhkQVZgmQ",
"version" : {
"number" : "8.4.3",
"build_flavor" : "default",
"build_type" : "zip",
"build_hash" : "42f05b9372a9a4a470db3b52817899b99a76ee73",
"build_date" : "2022-10-04T07:17:24.662462378Z",
"build_snapshot" : false,
"lucene_version" : "9.3.0",
"minimum_wire_compatibility_version" : "7.17.0",
"minimum_index_compatibility_version" : "7.0.0"
},
"tagline" : "You Know, for Search"
}

创建索引

请求方式:put

请求url:协议://主机:端口/索引名称

例如创建一个名为blog的索引

1
curl -X PUT http://localhost:9200/blog

响应

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

如果在发送请求之前,已经存在了对应的索引,就会返回类似以下的json数据

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

查看索引

请求方式:get

请求url:协议://主机:端口/索引名称

例如查看一个名为blog的索引

1
curl -X GET http://localhost:9200/blog

响应

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
{
"blog": {
"aliases": {},
"mappings": {},
"settings": {
"index": {
"routing": {
"allocation": {
"include": {
"_tier_preference": "data_content"
}
}
},
"number_of_shards": "1",
"provided_name": "blog",
"creation_date": "1667011001364",
"number_of_replicas": "1",
"uuid": "kNkittLPQNa6gjfiIwMZ_Q",
"version": {
"created": "8040399"
}
}
}
}
}

查看所有索引

请求方式:get

请求url: 协议://主机:端口/_cat/indices?v

1
curl -X GET http://localhost:9200/_cat/indices?v

响应

1
2
3
health status index    uuid                   pri rep docs.count docs.deleted store.size pri.store.size
yellow open blog kNkittLPQNa6gjfiIwMZ_Q 1 1 0 0 225b 225b
yellow open shopping HP4ryUR-SXmqfZk4h-HEiw 1 1 0 0 225b 225b

删除索引

请求方式:delete

请求url:协议://主机:端口/索引名称

例如删除索引名称为blog的索引

1
curl -X DELETE http://localhost:9200/blog

响应

1
2
3
{
"acknowledged": true
}

向索引中添加数据

请求方式:post

要添加的数据在请求体中说明

请求url:协议://主机:端口/索引名称/_doc

例如向shopping索引中添加以下数据

1
2
3
4
{
"band": "oppo",
"price": "999"
}

请求:这里使用apifox发送请求,具体细节待补充

响应

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

自定义数据id(满足幂等性,post和put请求都可)

1
http://localhost:9200/shopping/_doc/1001

1
http://localhost:9200/shopping/_create/1001

响应

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

查询数据

请求方式:get

请求url:协议://主机:端口/索引名称/_doc/数据id

例如查询shopping索引中id为1001的数据

1
curl -X GET http://localhost:9200/shopping/1001

响应

1
2
3
4
5
6
7
8
9
10
11
12
{
"_index": "shopping",
"_id": "1001",
"_version": 1,
"_seq_no": 1,
"_primary_term": 1,
"found": true,
"_source": {
"band": "oppo",
"price": "999"
}
}

查询索引下的全部数据

请求方式:get

请求url:协议://主机:端口/索引名称/_search

例如查询shopping索引下的全部数据

1
curl -X http://localhost: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
{
"took": 2,
"timed_out": false,
"_shards": {
"total": 1,
"successful": 1,
"skipped": 0,
"failed": 0
},
"hits": {
"total": {
"value": 2,
"relation": "eq"
},
"max_score": 1.0,
"hits": [{
"_index": "shopping",
"_id": "Hmq9IYQBphg_n9gvanO6",
"_score": 1.0,
"_source": {
"band": "oppo",
"price": "999"
}
}, {
"_index": "shopping",
"_id": "1001",
"_score": 1.0,
"_source": {
"band": "oppo",
"price": "999"
}
}]
}
}

全量数据更新

请求方式:put

请求url:协议://主机:端口/索引名称/_doc/数据id

将修改的内容放在请求体中,格式为json

例如将id为1001的数据修改为以下内容

1
2
3
4
{
"band": "oppo",
"price": "8888"
}

请求:这里使用apifox发送请求,具体细节待补充

响应

1
2
3
4
5
6
7
8
9
10
11
12
13
{
"_index": "shopping",
"_id": "1001",
"_version": 2,
"result": "updated",
"_shards": {
"total": 2,
"successful": 1,
"failed": 0
},
"_seq_no": 2,
"_primary_term": 2
}

局部数据更新

请求方式:post(不满足幂等性,不能用put)

请求url:协议://主机:端口/索引名称/_update/数据id

请求体:json格式

1
2
3
4
5
{
"doc": {
你要修改的数据
}
}

例如修改1001的band中的"oppo"为"vivo"

请求体如下

1
2
3
4
5
{
"doc": {
"band": "vivo"
}
}

请求:这里使用apifox发送请求,具体细节待补充

响应

1
2
3
4
5
6
7
8
9
10
11
12
13
{
"_index": "shopping",
"_id": "1001",
"_version": 3,
"result": "updated",
"_shards": {
"total": 2,
"successful": 1,
"failed": 0
},
"_seq_no": 3,
"_primary_term": 2
}

删除索引下的某条数据

请求方式:delete

请求url:协议://主机:端口/索引名称/_doc/数据id

例如删除索引shopping下id为1001的数据

1
curl -X DELETE http://localhost:9200/shopping/_doc/1001

响应

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

条件查询

请求方式:get

请求url

  1. 请求参数放请求头:协议://主机:端口/索引名称/_search?q=键:值

    缺点:请求头中值为中文时容易出现乱码

  2. 请求参数放请求体:协议://主机:端口/索引名称/_search

    请求体如下,格式为json

    1
    2
    3
    4
    5
    6
    7
    {
    "query": {
    "match": {
    你的请求参数
    }
    }
    }

例如查询shopping索引下category=小米的记录

1
curl -X GET http://localhost:9200/shopping/_search/q=category:小米

1
curl -X GET http://localhost:9200/shopping/_search

请求体如下

1
2
3
4
5
6
7
{
"query": {
"match": {
"category": "小米"
}
}
}

全量查询

请求方式:get

请求url:协议://主机:端口/索引名称/_search

请求体如下

1
2
3
4
5
6
7
{
"query": {
"match_all": {

}
}
}

分页

在请求体中带上以下参数

1
2
"from": 从哪条记录开始(索引从0开始)// (页码 - 1) * 每页数据条数
"size": 每页的大小

例如

1
2
3
4
5
6
7
8
9
{
"query": {
"match_all": {

}
},
"from": 1, // 从第1条数据开始
"size": 5 // 每页大小为5页
}

只显示部分字段结果

在请求体中带上以下参数

1
"_source":[你想要显示的字段]

例如我想显示title和category两个字段的结果

1
2
3
4
5
6
7
8
9
10
{
"query": {
"match_all": {

}
},
"from": 1, // 从第1条数据开始
"size": 5, // 每页大小为5页
"_source": ["title", "category"] // 显示title和category两个字段的结果
}

排序

在请求体中带上以下参数

1
2
3
4
5
"sort": {
排序依据的字段:{
"order: "desc" or "asc"
}
}

例如依据price进行降序排序

1
2
3
4
5
6
7
8
9
10
11
12
13
{
"query": {
"match_all": {

}
},
"from": 1, // 从第1条数据开始
"size": 5, // 每页大小为5页
"_source": ["title", "category"], // 显示title和category两个字段的结果
"order": {
"price": "desc" // 依据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
{
"query": { // 查询
"bool": { // 条件查询
"must": [ // 必须匹配的规则,相当于AND
{
"match": { // 规则
你的规则
}
},
{
"match": { // 规则
你的规则
}
}
……
],
"should": [ // 可以匹配的规则·相当于OR
{
"match": { // 规则
你的规则
}
},
{
"match": { // 规则
你的规则
}
}
]
}
}
}

例如查询category=小米&&price=999的数据

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
{
"query": { // 查询
"bool": { // 条件查询
"must": [ // 必须匹配的规则
{
"match": { // 规则
category: "小米"
}
},
{
"match": { // 规则
"price": 999
}
}

]
}
}
}

例如查询category=小米||price=999的数据

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
{
"query": { // 查询
"bool": { // 条件查询
"should": [ // 可以匹配的规则
{
"match": { // 规则
category: "小米"
}
},
{
"match": { // 规则
"price": 999
}
}

]
}
}
}

范围查询

举个例子,查询price大于5000的数据

1
2
3
4
5
6
7
{
"filter": {
"range": {
"gt": 5000
}
}
}

全文检索匹配

以下语句可以匹配"小米"和"华为",原因在于elastic为倒排索引,“小华”被拆解成"小”、“华”、”小华“三个关键字,这叫全文检索匹配

1
2
3
4
5
6
7
{
"query": {
"match": { // match为全文检索匹配
"category": "小华"
}
}
}

完全匹配

以下语句仅匹配含有“小华”的数据

1
2
3
4
5
6
7
{
"query": {
"match_phase": { // 完全匹配
"category": "小华"
}
}
}

高亮显示

加入以下代码

对category字段进行高亮显示

1
2
3
4
5
"highlight": {
"fields": {
"category": {}
}
}

聚合操作

加入以下代码

表示对field进行分组

1
2
3
4
5
6
7
8
9
{
"aggs": { // 聚合操作
"price_group": { // 名称,随意起名
"terms": { // 分组
"field": "price" // 分组字段
}
}
}
}

不显示原来数据

1
2
3
4
5
6
7
8
9
10
{
"aggs": { // 聚合操作
"price_group": { // 聚合操作后的返回数据名称,名称自定义
"terms": { // 分组
"field": "price" // 分组字段
}
}
},
"size": 0 // 表示不显示原来数据
}

不分组,求平均值

1
2
3
4
5
6
7
8
9
10
{
"aggs": { // 聚合操作
"price_avg": { // 聚合操作后的返回数据名称,名称自定义
"avg": { // 求平均值
"field": "price" // 求平均值的字段
}
}
},
"size": 0 // 表示不显示原来数据
}

映射关系

在mysql中,一个表的字段、类型、长度都属于它的结构信息,在es中也有类似的概念,我们称之为映射关系

创建映射

请求方式:put

请求url:协议://主机:端口/索引名称/_mapping

请求体示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
{
"properties": {
"name": {
"type": "text", // text表示可以被分词
"index": true
},
"sex": {
"type": "keyword", // keyword表示不能被分词
"index": true // true表示可以被索引
},
"tel": {
"type": "keyword",
"index": false // false表示不能被索引
}
}
}