Elasticsearch应用开发人员应该熟练掌握的REST API
📅 2021-05-21 | 🖱️
ES为提供了一套HTTP RESTful API,开发和运维人员可以直接调用这些API来配置和访问ES服务。 这些API的功能十分丰富,从集群监控、运维管理到应用开发所需的索引、文档相关操作。本文将从应用开发的角度整理ES应用开发人员应该熟练掌握的API。
1.索引的创建、修改和删除 #
创建索引PUT /<index-name>
,例:
1PUT /book-0.1.0
2{
3 "aliases": {
4 "book":{}
5 },
6 "settings": {
7 "analysis": {
8 "normalizer": {
9 "lowercase": {
10 "type": "custom",
11 "char_filter": [],
12 "filter": ["lowercase"]
13 }
14 }
15 }
16 },
17 "mappings": {
18 "properties": {
19 "name": {
20 "type": "keyword",
21 "normalizer": "lowercase"
22 },
23 "price": {
24 "type": "double"
25 },
26 "summary": {
27 "type": "text",
28 "analyzer": "ik_max_word"
29 },
30 "author": {
31 "type": "keyword"
32 },
33 "pubDate": {
34 "type": "date"
35 }
36 }
37 }
38}
实践中在创建索引时,索引的名称一般会带上版本号,同时将不带版本号的名称设置为索引的别名(alias),开发中对索引文档的操作都是基于别名。 通过索引别名可以优雅的解决两个版本索引之间的无缝切换问题。
删除索引DELETE /<index-name>
,例:
1DELETE /book-0.1.0
查看索引信息GET /<index-name>
,例:
1GET /book-0.1.0
在应用开发的各个迭代过程中,经常需要对一个索引的mapping结构进行调整。 如果调整结构的需求是增加新的字段,可以直接调用API增加,如果是修改现有字段或删除现有字段,则只能通过创建新mapping结构的索引并重新reindex数据的方式实现。 调用API增加新字段举例如下:
1PUT /book-0.1.0/_mapping
2{
3 "properties": {
4 "pages": {
5 "type": "integer"
6 }
7 }
8}
2.文档的创建 #
索引创建好后就可以直接向索引中添加数据了。
1PUT /<index-name>/_doc/<_id>
2
3POST /<index-name>/_doc/
4
5PUT /<index-name>/_create/<_id>
6
7POST /<index-name>/_create/<_id>
1POST /book/_doc
2{
3 "name": "天龙八部",
4 "author": "金庸",
5 "pages": 1978,
6 "price": 96.0,
7 "pubDate": "1994-05-01",
8 "summary": "天龙八部乃金笔下的一部长篇小说,与《射雕》,《神雕》等 几部长篇小说一起被称为可读性最高的金庸小说。《天龙》的故事情节曲折,内容丰富,也曾多次被改编为电视作品。是金庸作品中集大成的一部。故事以北宋末年动荡的社会环境为背景,展开波澜壮阔的历史画卷,塑造了乔峰、段誉、 虚竹、慕容复等形象鲜明的人物,成为武侠史上的经典之作。"
9}
10
11输出:
12{
13 "_index" : "book-0.1.0",
14 "_type" : "_doc",
15 "_id" : "y2W-mHkB3xk21-h8U9AP",
16 "_version" : 1,
17 "result" : "created",
18 "_shards" : {
19 "total" : 2,
20 "successful" : 2,
21 "failed" : 0
22 },
23 "_seq_no" : 0,
24 "_primary_term" : 1
25}
文档创建成功后,会返回一个包含_id
的json数据,_id
即为刚刚创建的文档的ID由ES自动生成,唯一标识一个文档。
POST /<target>/_doc/
这个API不具有幂等性,多次请求会创建_id
不同的,但文档其他字段相同的重复数据。
可以在创建文档时手动指定文档ID:
1POST /book/_doc/10001
2{
3 "name": "天龙八部",
4 "author": "金庸",
5 "pages": 1978,
6 "price": 96.0,
7 "pubDate": "1994-05-01",
8 "summary": "天龙八部乃金笔下的一部长篇小说,与《射雕》,《神雕》等 几部长篇小说一起被称为可读性最高的金庸小说。《天龙》的故事情节曲折,内容丰富,也曾多次被改编为电视作品。是金庸作品中集大成的一部。故事以北宋末年动荡的社会环境为背景,展开波澜壮阔的历史画卷,塑造了乔峰、段誉、 虚竹、慕容复等形象鲜明的人物,成为武侠史上的经典之作。"
9}
文档创建成功后,返回的_id
为我们指定的ID值,多次发出这个创建请求,返回的结果是相同的,只是返回数据版本_version
会增加。
操作是幂等的,也可以将上面的POST
请求方式换成PUT
请求。另外可以使用PUT /<index-name>/_create/<_id>
或POST /<index-name>/_create/<_id>
创建文档时,如果_id
已经存在时会失败并报版本冲突的错误,实际根据具体的需求选择使用哪个API。
3.文档的查询 #
使用GET <index-name>/_doc/<_id>
API查询指定ID的文档:
例如:
1GET /book/_doc/10001
2
3输出:
4{
5 "_index" : "book-0.1.0",
6 "_type" : "_doc",
7 "_id" : "10001",
8 "_version" : 5,
9 "_seq_no" : 7,
10 "_primary_term" : 1,
11 "found" : true,
12 "_source" : {
13 "name" : "天龙八部",
14 "author" : "金庸",
15 "pages" : 1978,
16 "price" : 96.0,
17 "pubDate" : "1994-05-01",
18 "summary" : ......
19 }
20}
使用GET <index-name>/_search
查询所有的文档数据:
1GET /book/_search
4.文档的更新和删除 #
更新文档包含两种情况,一种是完全覆盖性更新,另一种是局部性更新。
先来看完全覆盖性更新:
1PUT /book/_doc/10001
2{
3 "name": "天龙八部",
4 "author": "金庸",
5 "pages": 1978,
6 "price": 96.0,
7 "pubDate": "1994-05-01",
8 "summary": ""
9}
再来看局部性更新:
1POST /book/_update/10001
2{
3 "doc": {
4 "name": "《天龙八部》"
5 }
6}
文档的删除:
1DELETE /book/_update/10001
5.条件查询、分页和排序 #
前面已经介绍了文档的增、删、改、查,ES的优势还是在查询上。
简单的条件查询、分页和排序如下例:
1GET /book/_search
2{
3 "query": {
4 "match": {
5 "author": "金庸"
6 }
7 },
8 "from": 0,
9 "size": 5,
10 "sort": [
11 {
12 "price": {
13 "order": "desc"
14 }
15 }
16 ]
17}
6.多条件查询和范围查询 #
多条件查询如下例:
1# 多条件同时成立
2GET /book/_search
3{
4 "query": {
5 "bool": {
6 "must": [
7 {
8 "match": {
9 "author": "金庸"
10 }
11 },
12 {
13 "match": {
14 "pages": 1978
15 }
16 }
17 ]
18 }
19 }
20}
21
22# 多条件满足其一即可
23GET /book/_search
24{
25 "query": {
26 "bool": {
27 "should": [
28 {
29 "match": {
30 "author": "金庸"
31 }
32 },
33 {
34 "match": {
35 "pages": 1978
36 }
37 }
38 ]
39 }
40 }
41}
范围查询如下例:
1GET /book/_search
2{
3 "query": {
4 "bool": {
5 "must": [
6 {
7 "match": {
8 "author": "金庸"
9 }
10 },
11 {
12 "range": {
13 "price": {
14 "gte":50,
15 "lte": 100
16 }
17 }
18 }
19 ]
20 }
21 }
22}
7.全文检索与完全匹配 #
文档字段为text类型时,会将查询关键字进行分词并在倒排索引中进行匹配。
1GET /book/_search
2{
3 "query": {
4 "match": {
5 "summary": "北宋射雕"
6 }
7 }
8}
完全匹配:
1GET /book/_search
2{
3 "query": {
4 "match_phrase": {
5 "author": "金庸"
6 }
7 }
8}
高亮显示:
1GET /book/_search
2{
3 "query": {
4 "match": {
5 "summary": "北宋射雕"
6 }
7 },
8 "highlight": {
9 "fields": {
10 "summary": {}
11 }
12 }
13}
8.聚合查询 #
下面的例子,使用aggs
进行聚合查询,设置"size": 0
只返回聚合统计结果,不要返回查询的hits结果。
1GET /book/_search
2{
3 "aggs": {
4 "author_agg_name": {
5 "terms": {
6 "field": "author"
7 }
8 }
9 },
10 "size": 0
11}
例如查询作者为金庸的所有图书的平均价格:
1GET /book/_search
2{
3 "query": {
4 "match_phrase": {
5 "author": "金庸"
6 }
7 },
8 "aggs": {
9 "avg_price": {
10 "avg": {
11 "field": "price"
12 }
13 }
14 },
15 "size": 0
16}