ElasticSearch Rest基本操作

一、REST 定义

REST (REpresentation State Transfer)描述了一个架构样式的网络系统,比如 web 应用程序。它首次出现在2000 年 Roy Fielding 的博士论文中,他是 HTTP 规范的主要编写者之一。REST指的是一组架构约束条件和原则。满足这些约束条件和原则的应用程序或设计就是 RESTful。
Web 应用程序最重要的 REST 原则是,客户端和服务器之间的交互在请求之间是无状态的。从客户端到服务器的每个请求都必须包含理解请求所必需的信息。如果服务器在请求之间的任何时间点重启,客户端不会得到通知。此外,无状态请求可以由任何可用服务器回答,这十分适合云计算之类的环境。客户端可以缓存数据以改进性能。
在服务器端,应用程序状态和功能可以分为各种资源。资源是一个有趣的概念实体,它向客户端公开。资源的例子有:应用程序对象、数据库记录、算法等等。每个资源都使用URI (Universal Resource Identifier)得到一个惟一的地址。所有资源都共享统一的界面,以便在客户端和服务器之间传输状态。使用的是标准的 HTTP 方法,比如GET、PUT、POST 和DELETE。

二、REST 资源

资源GETPUTPUTDELETE
一组资源的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}}'

如果传递的版本号和待更新的文档的版本号不一致,则会更新失败。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Dustin.Hoffman

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值