目录
一、REST 定义
REST (REpresentation State Transfer)描述了一个架构样式的网络系统,比如 web 应用程序。它首次出现在2000 年 Roy Fielding 的博士论文中,他是 HTTP 规范的主要编写者之一。REST指的是一组架构约束条件和原则。满足这些约束条件和原则的应用程序或设计就是 RESTful。
Web 应用程序最重要的 REST 原则是,客户端和服务器之间的交互在请求之间是无状态的。从客户端到服务器的每个请求都必须包含理解请求所必需的信息。如果服务器在请求之间的任何时间点重启,客户端不会得到通知。此外,无状态请求可以由任何可用服务器回答,这十分适合云计算之类的环境。客户端可以缓存数据以改进性能。
在服务器端,应用程序状态和功能可以分为各种资源。资源是一个有趣的概念实体,它向客户端公开。资源的例子有:应用程序对象、数据库记录、算法等等。每个资源都使用URI (Universal Resource Identifier)得到一个惟一的地址。所有资源都共享统一的界面,以便在客户端和服务器之间传输状态。使用的是标准的 HTTP 方法,比如GET、PUT、POST 和DELETE。
二、REST 资源
资源 | GET | PUT | PUT | DELETE |
---|---|---|---|---|
一组资源的URLhttp://example.com/products/ | 列出URL列表 | 使用给定的一组资源替换当前组资源 | 在本资源组中创建或者追加一个新的资源 | 删除整组资源 |
单个资源的URLhttp://example.com/products/4554 | 获取指定资源的详细信息 | 替换或者创建指定资源 | 在资源组下创建或者追加一个新的元素 | 删除指定的元素 |
三、REST基本操作
GET 获取对象的当前状态
PUT 改变对象的状态
POST 创建对象
DELETE 删除对象
HEAD 获取头信息
四、ES 内置的REST接口
URL | 说明 |
---|---|
/index/_search | 搜索指定索引下的数据 |
/_aliases | 获取或者操作索引下的别名 |
/index/ | 查看指定索引下的详细信息 |
/index/type/ | 创建或者操作类型 |
/index/mapping | 创建或者操作mapping |
/index/settings | 创建或者操作settings |
/index/_open | 打开指定索引 |
/index/_close | 关闭指定索引 |
/index/_refresh | 刷新索引(使新增加内容对搜索可见,不保证数据被写入磁盘) |
/index/_flush | 刷新索引(会触发Lucene提交数据) |
五、CURL命令
简单认为是可以在命令行下访问url的一个工具 curl是利用URL语法在命令行方式下工作的开源文件传输工具,使用curl可以简单实现常见的get/post请求。
Curl的使用
-X 指定http请求的方法GET、POST、PUT、DELETE
-d 指定要传递的参数
六、CURL 创建索引库
示例:
创建索引,使用PUT/POST都可以
[root@es1 ~]# curl -XPUT 'http://192.168.1.3:9200/test/'
插入一条数据:
[root@es1 ~]# curl -H "Content-Type: application/json" -XPOST http://192.168.1.3:9200/test/user/1 -d '{"name" : "jack","age" : 28}'
创建索引库注意事项:
1、索引库名称必须要全部小写,不能以下划线开头,也不能包含逗号;
2、如果没有明确指定索引数据的ID,那么es会自动生成一个随机的ID,需要使用POST参数:
[root@es1 ~]# curl -H "Content-Type: application/json" -XPOST http://master:9200/test/user/ -d '{"name" : "john"}'
3、创建全新内容的两种方式:
(1)使用自增ID(post);
(2)在url后面添加参数,如:
[root@es1 ~]# curl -H "Content-Type: application/json" -XPUT http://192.168.1.3:9200/test/user/2?op_type=create -d '{"name":"lucy","age":18}'
[root@es1 ~]# curl -H "Content-Type: application/json" -XPUT http://192.168.1.3:9200/test/user/3/_create -d '{"name":"lily","age":28}'
PUT和POST的用法区别:
(1)PUT是幂等方法,而POST并不是。所以PUT用于更新操作、POST用于新增操作比较合适。
(2)PUT,DELETE操作是幂等的。所谓幂等是指不管进行多少次操作,结果都一样。比如我用PUT修改一篇文章,然后在做同样的操作,每次操作后的结果并没有不同,DELETE也是一样。
(3)POST操作不是幂等的,比如常见的POST重复加载问题:当我们多次发出同样的POST请求后,其结果是创建出了若干的资源。
(4)还有一点需要注意的就是,创建操作可以使用POST,也可以使用PUT,区别在于POST是作用在一个集合资源之上的(/articles),而PUT操作是作用在一个具体资源之上的(/articles/123),比如说很多资源使用数据库自增主键作为标识信息,而创建的资源的标识信息到底是什么只能由服务端提供,这个时候就必须使用POST。
七、查询索引-GET
根据员工id查询:
[root@es1 ~]# curl -XGET http://192.168.1.3:9200/test/user/1?pretty
{
"_index" : "test",
"_type" : "user",
"_id" : "1",
"_version" : 5,
"_seq_no" : 5,
"_primary_term" : 1,
"found" : true,
"_source" : {
"name" : "zhangsan",
"age" : 28
}
}
检索文档中的一部分,如果只需要显示指定字段:
[root@es1 ~]# curl -XGET 'http://192.168.1.3:9200/test/user/1?_source=name&pretty'
{
"_index" : "test",
"_type" : "user",
"_id" : "1",
"_version" : 5,
"_seq_no" : 5,
"_primary_term" : 1,
"found" : true,
"_source" : {
"name" : "zhangsan"
}
}
查询指定索引库指定类型所有数据:
[root@es1 ~]# curl -XGET http://192.168.1.3:9200/test/user/_search?pretty
{
"took" : 8,
"timed_out" : false,
"_shards" : {
"total" : 1,
"successful" : 1,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 7,
"relation" : "eq"
},
"max_score" : 1.0,
"hits" : [
{
"_index" : "test",
"_type" : "user",
"_id" : "v3g7FXEBCgkolMDYDfxt",
"_score" : 1.0,
"_source" : {
"name" : "zhangsan",
"age" : 28
}
......
}
]
}
}
根据条件进行查询:
[root@es1 ~]# curl -XGET 'http://192.168.1.3:9200/test/user/_search?q=name:john&pretty'
{
"took" : 19,
"timed_out" : false,
"_shards" : {
"total" : 1,
"successful" : 1,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 0,
"relation" : "eq"
},
"max_score" : null,
"hits" : [ ]
}
}
DSL查询:
Domain Specific Language领域特定语言
新添加一个文档:
[root@es1 ~]# curl -H "Content-Type: application/json" -XPUT http://192.168.1.3:9200/test/user/4/_create -d '{"name":"qiqi","age":17}'
[root@es1 ~]# curl -H "Content-Type: application/json" -XGET http://192.168.1.3:9200/test/user/_search -d'{"query":{"match":{"name":"qiqi"}}}'
以下为返回的响应信息:
{"took":1,"timed_out":false,"_shards":{"total":1,"successful":1,"skipped":0,"failed":0},"hits":{"total":{"value":1,"relation":"eq"},"max_score":1.6739764,"hits":[{"_index":"test","_type":"user","_id":"4","_score":1.6739764,"_source":{"name":"qiqi","age":17}
八、MGET查询
使用mget API获取多个文档:
先新建一个库,并插入一条数据
[root@logstash es1]# curl -XPUT 'http://192.168.1.3:9200/test2/'
[root@logstash es1]# curl -H "Content-Type: application/json" -XPOST http://192.168.1.3:9200/test2/user/1 -d '{"name" : "marry","age" : 16}'
查询两个索引中的数据:
[root@es1 ~]# curl -H "Content-Type: application/json" -XGET http://192.168.1.3:9200/_mget?pretty -d '{"docs":[{"_index":"test","_type":"user","_id":2,"_source":"name"},{"_index":"test2","_type":"user","_id":1}]}'
以下为响应信息:
{
"docs" : [
{
"_index" : "test",
"_type" : "user",
"_id" : "2",
"_version" : 1,
"_seq_no" : 6,
"_primary_term" : 1,
"found" : true,
"_source" : {
"name" : "zll"
}
},
{
"_index" : "test2",
"_type" : "user",
"_id" : "1",
"_version" : 5,
"_seq_no" : 4,
"_primary_term" : 1,
"found" : true,
"_source" : {
"name" : "marry",
"age" : 16
}
}
]
}
如果需要的文档在同一个_index或者同一个_type中,你就可以在URL中指定一个默认的/_index或者/_index/_type:
[root@es1 ~]# curl -H "Content-Type: application/json" -XGET http://192.168.1.3:9200/test/user/_mget?pretty -d '{"docs":[{"_id":1},{"_id":2}]}'
{
"docs" : [
{
"_index" : "test",
"_type" : "user",
"_id" : "1",
"_version" : 5,
"_seq_no" : 5,
"_primary_term" : 1,
"found" : true,
"_source" : {
"name" : "zhangsan",
"age" : 28
}
},
{
"_index" : "test",
"_type" : "user",
"_id" : "2",
"_version" : 1,
"_seq_no" : 6,
"_primary_term" : 1,
"found" : true,
"_source" : {
"name" : "zll",
"age" : 28
}
}
]
}
如果所有的文档拥有相同的_index 以及 _type,直接在请求中添加ids的数组即:
[root@es1 ~]# curl -H "Content-Type: application/json" -XGET http://192.168.1.3:9200/test/user/_mget?pretty -d '{"ids":["1","2"]}'
九、ES更新
ES可以使用PUT或者POST对文档进行更新(全部更新),如果指定ID的文档已经存在,则执行更新操作。注意:执行更新操作的时候, ES首先将旧的文档标记为删除状态 然后添加新的文档,旧的文档不会立即消失,但是你也无法访问,ES会在你继续添加更多数据的时候,在后台清理已经标记为删除状态的文档。
局部更新,可以添加新字段或者更新已有字段(必须使用POST):
[root@es1 ~]# curl -H "Content-Type: application/json" -XPOST http://192.168.1.3:9200/test/user/1/_update -d '{"doc":{"name":"baby","age":27}}'
十、ES删除
在执行删除脚本时,如果要删除的文档存在,则result属性值为deleted,_version属性的值+1;
如果文档不存在,则result属性值为not_found,但是_version属性的值依然会+1,这个就是内部管理的一部分,它保证了我们在多个节点间的不同操作的顺序都被正确标记了。
注意:删除一个文档也不会立即生效,它只是被标记成已删除。Elasticsearch将会在你之后添加更多索引的时候才会在后台进行删除内容的清理。
删除操作:
[root@es1 ~]# curl -XDELETE http://192.168.1.3:9200/test/user/1?pretty
{
"_index" : "test",
"_type" : "user",
"_id" : "1",
"_version" : 1,
"result" : "deleted",
"_shards" : {
"total" : 2,
"successful" : 2,
"failed" : 0
},
"_seq_no" : 12,
"_primary_term" : 1
}
可以看到result的值是deleted,version是1,下面我们再次执行这条命令:
[root@es1 ~]# curl -XDELETE http://192.168.1.3:9200/test/user/1?pretty
{
"_index" : "test",
"_type" : "user",
"_id" : "1",
"_version" : 2,
"result" : "not_found",
"_shards" : {
"total" : 2,
"successful" : 2,
"failed" : 0
},
"_seq_no" : 13,
"_primary_term" : 1
}
现在执行之后,result变成了not_found,version变成了2。也就是说这条命令执行成功,但是数据没找到。
十一、ES批量操作-bulk
bulk API可以帮助我们同时执行多个请求,格式如下:
action:index/create/update/delete
metadata:_index,_type,_id
request body:_source(删除操作不需要)
{ action: { metadata }}
{ request body }
{ action: { metadata }}
{ request body }
create 和index的区别:如果数据存在,使用create操作失败,会提示文档已经存在,使用index则可以成功执行。
使用文件的方式,新建一个requests文件:
[root@es1 ~]# vim requests
{"index":{"_index":"test","_type":"user","_id":"6"}}
{"name":"ma","age":51}
{"update":{"_index":"test","_type":"user","_id":"6"}}
{"doc":{"age":52}}
执行批量操作:
[root@es1 ~]# curl -H "Content-Type: application/json" -XPOST http://192.168.1.3:9200/_bulk --data-binary @requests
查询数据是否插入并更新成功:
[root@es1 ~]# curl -H "Content-Type application/json" -XGET 'http://192.168.1.3:9200/test/user/6?pretty'
{
"_index" : "test",
"_type" : "user",
"_id" : "6",
"_version" : 2,
"_seq_no" : 15,
"_primary_term" : 1,
"found" : true,
"_source" : {
"name" : "ma",
"age" : 52
}
}
以上可以看出,数据成功插入,且age更新为52了。
bulk请求可以在URL中声明/_index 或者/_index/_type.。
bulk一次最大处理多少数据量:
1)bulk会把将要处理的数据载入内存中,所以数据量是有限制的.
2)最佳的数据量不是一个确定的数值,它取决于你的硬件,你的文档大小以及复杂性,你的索引以及搜索的负载.
3)一般建议是1000-5000个文档,如果你的文档很大,可以适当减少队列,大小建议是5-15MB,默认不能超过100M,可以在es的配置文件中修改这个值http.max_content_length:100mb。
十二、ES版本控制
ES使用的是乐观并发控制(OCC),ES不会阻止某一数据的访问,然而,如果基础数据在我们读取和写入的间隔中发生了变化,更新就会失败,这时候就由程序来决定如何处理这个冲突。它可以重新读取新数据来进行更新,又或者将这一情况直接反馈给用户。
ES如何实现版本控制(使用es内部版本号):
首先得到需要修改的文档,获取版本(_version)号:
[root@es1 ~]# curl -XGET http://192.168.1.3:9200/test/user/2
在执行更新操作的时候把版本号传过去:
[root@es1 ~]# curl -H "Content-Type: application/json" -XPUT http://192.168.1.3:9200/test/user/2?version=1 -d '{"name":"john","age":29}'
[root@es1 ~]# curl -H "Content-Type: application/json" -XPOST http://192.168.1.3:9200/test/user/2/_update?version=2 -d '{"doc":{"age":30}}'
如果传递的版本号和待更新的文档的版本号不一致,则会更新失败。