ElasticSearch 常用API

数据操作

官方API文档:https://www.elastic.co/guide/en/elasticsearch/reference/current/docs.html

中文API文档:https://doc.codingdict.com/elasticsearch/

常用API

curl -XGET 'localhost:9200/_cat/health?v&pretty'    #集群健康
curl -XGET 'localhost:9200/_cat/nodes?v&pretty'		#查看所有节点
curl -XGET 'localhost:9200/_cat/indices?v&pretty'	#查看所有索引
curl -XGET 'http://192.168.0.100:9202/_cluster/stats?pretty' #查看集群详细信息
curl -XPUT 'localhost:9200/customer?pretty&pretty'    #创建一个名为 “customer” 的索引

# 索引一个简单的 customer 文档到 customer 索引中,“external” 类型,与一个为 1 的 ID
curl -XPUT 'localhost:9200/customer/external/1?pretty&pretty' -d'
{
  "name": "John Doe"
}'

curl -XGET 'localhost:9200/customer/external/1?pretty&pretty'  #检索我们刚刚索引的文档
curl -XDELETE 'localhost:9200/customer?pretty&pretty'   #删除刚创建的索引

#如果仔细研究上面的命令,可以清楚的看到,如何访问 Elasticsearch 中的数据的 pattern(模式)。该 pattern(模式)可以概括如下 :
<REST Verb> /<Index>/<Type>/<ID>

搜索 API

现在让我们从一些简单的搜索开始。这里两个运行搜索的基本方法 : 一个是通过使用 REST request URI 发送搜索参数,另一个是通过使用 REST request body 来发送它们。请求体的方法可以让您更具有表现力,并且可以在一个更可读的 JSON 格式中定义您的搜索。我们会尝试使用一个 REST request URI 的示例,但是在本教程的其它部分,我们将只使用 REST request body 的方法。

搜索的 REST API_search 的尾部开始。这个示例返回了 bank 索引中的所有文档 :

curl -XGET 'localhost:9200/bank/_search?q=*&sort=account_number:asc&pretty'

首先让我们切开搜索的调用。我们在 bank 索引中执行搜索(_search 尾部),然后 q=参数命令Elasticsearch去匹配索引中所有的文档。pretty 参数,再一次告诉 Elasticsearch 去返回打印漂亮的 JSON** 结果。

响应如下(部分):

{
  "took" : 63,
  "timed_out" : false,
  "_shards" : {
    "total" : 5,
    "successful" : 5,
    "failed" : 0
  },
  "hits" : {
    "total" : 1000,
    "max_score" : null,
    "hits" : [ {
      "_index" : "bank",
      "_type" : "account",
      "_id" : "0",
      "sort": [0],
      "_score" : null,
      "_source" : {"account_number":0,"balance":16623,"firstname":"Bradshaw","lastname":"Mckenzie","age":29,"gender":"F","address":"244 Columbus Place","employer":"Euron","email":"bradshawmckenzie@euron.com","city":"Hobucken","state":"CO"}
    }, {
      "_index" : "bank",
      "_type" : "account",
      "_id" : "1",
      "sort": [1],
      "_score" : null,
      "_source" : {"account_number":1,"balance":39225,"firstname":"Amber","lastname":"Duke","age":32,"gender":"M","address":"880 Holmes Lane","employer":"Pyrami","email":"amberduke@pyrami.com","city":"Brogan","state":"IL"}
    }, ...
    ]
  }
}

在响应中,我们可以看到以下几个部分 :

  • took - Elasticsearch 执行搜索的时间(毫秒)
  • time_out - 告诉我们搜索是否超时
  • _shards - 告诉我们多少个分片被搜索了,以及统计了成功/失败的搜索分片
  • hits - 搜索结果
  • hits.total - 搜索结果
  • hits.hits - 实际的搜索结果数组(默认为前 10 的文档)
  • sort - 结果的排序 key(键)(没有则按 score 排序)
  • scoremax_score -现在暂时忽略这些字段

这里是上面相同的搜索,使用了 REST request body 方法 :

curl -XGET 'localhost:9200/bank/_search?pretty' -d'
{
  "query": { "match_all": {} },
  "sort": [
    { "account_number": "asc" }
  ]
}'

这里不同的地方是而不是在 URL 中传递 q= **,我们* *POST* 一个 JSON 风格的查询请求体到 _search API。我们将在下一部分讨论这个 JSON** 查询。

需要了解,一旦您搜索的结果被返回,Elasticsearch 完成了这次请求,并且不会维护任何服务端的资源或者结果的 cursor(游标)。这与其它的平台形成了鲜明的对比,例如 SQL,您可能首先获得查询结果的子集,如果您想要使用一些服务端有状态的 cursor(光标)来抓取(或者通过分页)其它的结果,然后您必须再次回到服务器。

新增记录

向指定的 /Index/Type 发送 PUT 请求,就可以在 Index 里面新增一条记录。比如,向/accounts/person发送请求,就可以新增一条人员记录。

curl -X PUT 'localhost:9200/accounts/person/1' -d '
{
  "user": "张三",
  "title": "工程师",
  "desc": "数据库管理"
}' 

服务器返回的 JSON 对象,会给出 Index、Type、Id、Version 等信息。

{
  "_index":"accounts",
  "_type":"person",
  "_id":"1",
  "_version":1,
  "result":"created",
  "_shards":{"total":2,"successful":1,"failed":0},
  "created":true
}

如果你仔细看,会发现请求路径是/accounts/person/1,最后的1是该条记录的 Id。它不一定是数字,任意字符串(比如abc)都可以。

新增记录的时候,也可以不指定 Id,这时要改成 POST 请求。

$ curl -X POST 'localhost:9200/accounts/person' -d '
{
  "user": "李四",
  "title": "工程师",
  "desc": "系统管理"
}'

上面代码中,向/accounts/person发出一个 POST 请求,添加一个记录。这时,服务器返回的 JSON 对象里面,_id字段就是一个随机字符串。

{
  "_index":"accounts",
  "_type":"person",
  "_id":"AV3qGfrC6jMbsbXb6k1p",
  "_version":1,
  "result":"created",
  "_shards":{"total":2,"successful":1,"failed":0},
  "created":true
}

注意,如果没有先创建 Index(这个例子是accounts),直接执行上面的命令,Elastic 也不会报错,而是直接生成指定的 Index。所以,打字的时候要小心,不要写错 Index 的名称。

查看记录

/Index/Type/Id发出 GET 请求,就可以查看这条记录。

curl 'localhost:9200/accounts/person/1?pretty=true'

上面代码请求查看/accounts/person/1这条记录,URL 的参数pretty=true表示以易读的格式返回。

返回的数据中,found字段表示查询成功,_source字段返回原始记录。

{
  "_index" : "accounts",
  "_type" : "person",
  "_id" : "1",
  "_version" : 1,
  "found" : true,
  "_source" : {
    "user" : "张三",
    "title" : "工程师",
    "desc" : "数据库管理"
  }
}

如果 Id 不正确,就查不到数据,found字段就是false

$ curl 'localhost:9200/weather/beijing/abc?pretty=true'

{
  "_index" : "accounts",
  "_type" : "person",
  "_id" : "abc",
  "found" : false
}

删除记录

删除记录就是发出 DELETE 请求。

curl -X DELETE 'localhost:9200/accounts/person/1'

这里先不要删除这条记录,后面还要用到。

更新记录

更新记录就是使用 PUT 请求,重新发送一次数据。

$ curl -X PUT 'localhost:9200/accounts/person/1' -d '
{
    "user" : "张三",
    "title" : "工程师",
    "desc" : "数据库管理,软件开发"
}' 

{
  "_index":"accounts",
  "_type":"person",
  "_id":"1",
  "_version":2,
  "result":"updated",
  "_shards":{"total":2,"successful":1,"failed":0},
  "created":false
}

上面代码中,我们将原始数据从"数据库管理"改成"数据库管理,软件开发"。 返回结果里面,有几个字段发生了变化。

"_version" : 2,
"result" : "updated",
"created" : false

可以看到,记录的 Id 没变,但是版本(version)从1变成2,操作类型(result)从created变成updatedcreated字段变成false,因为这次不是新建记录。

数据查询

返回所有记录

使用 GET 方法,直接请求/Index/Type/_search,就会返回所有记录。

curl 'localhost:9200/accounts/person/_search'

{
  "took":2,
  "timed_out":false,
  "_shards":{"total":5,"successful":5,"failed":0},
  "hits":{
    "total":2,
    "max_score":1.0,
    "hits":[
      {
        "_index":"accounts",
        "_type":"person",
        "_id":"AV3qGfrC6jMbsbXb6k1p",
        "_score":1.0,
        "_source": {
          "user": "李四",
          "title": "工程师",
          "desc": "系统管理"
        }
      },
      {
        "_index":"accounts",
        "_type":"person",
        "_id":"1",
        "_score":1.0,
        "_source": {
          "user" : "张三",
          "title" : "工程师",
          "desc" : "数据库管理,软件开发"
        }
      }
    ]
  }
}

上面代码中,返回结果的 took字段表示该操作的耗时(单位为毫秒),timed_out字段表示是否超时,hits字段表示命中的记录,里面子字段的含义如下。

  • total:返回记录数,本例是2条。
  • max_score:最高的匹配程度,本例是1.0
  • hits:返回的记录组成的数组。

返回的记录中,每条记录都有一个_score字段,表示匹配的程序,默认是按照这个字段降序排列。

全文搜索

Elastic 的查询非常特别,使用自己的查询语法,要求 GET 请求带有数据体。

curl 'localhost:9200/accounts/person/_search'  -d '
{
  "query" : { "match" : { "desc" : "软件" }}
}'

上面代码使用 Match 查询,指定的匹配条件是desc字段里面包含"软件"这个词。返回结果如下。

{
  "took":3,
  "timed_out":false,
  "_shards":{"total":5,"successful":5,"failed":0},
  "hits":{
    "total":1,
    "max_score":0.28582606,
    "hits":[
      {
        "_index":"accounts",
        "_type":"person",
        "_id":"1",
        "_score":0.28582606,
        "_source": {
          "user" : "张三",
          "title" : "工程师",
          "desc" : "数据库管理,软件开发"
        }
      }
    ]
  }
}

Elastic 默认一次返回10条结果,可以通过size字段改变这个设置。

curl 'localhost:9200/accounts/person/_search'  -d '
{
  "query" : { "match" : { "desc" : "管理" }},
  "size": 1
}'

上面代码指定,每次只返回一条结果。

还可以通过from字段,指定位移。

curl 'localhost:9200/accounts/person/_search'  -d '
{
  "query" : { "match" : { "desc" : "管理" }},
  "from": 1,
  "size": 1
}'

上面代码指定,从位置1开始(默认是从位置0开始),只返回一条结果。

逻辑运算

如果有多个搜索关键字, Elastic 认为它们是or关系。

curl 'localhost:9200/accounts/person/_search'  -d '
{
  "query" : { "match" : { "desc" : "软件 系统" }}
}'

上面代码搜索的是软件 or 系统

如果要执行多个关键词的and搜索,必须使用布尔查询

curl 'localhost:9200/accounts/person/_search'  -d '
{
  "query": {
    "bool": {
      "must": [
        { "match": { "desc": "软件" } },
        { "match": { "desc": "系统" } }
      ]
    }
  }
}'

批处理

除了可以索引,更新,和删除单个的文档之外,Elasticsearch 还提供了使用 _bulk API 来执行上面任何操作的批量方式的能力。这个功能是非常重要,它提供了一种非常有效的机制,以尽可能减少网络返回且尽可能快的执行多个操作。

作为一个简单的例子,在一个批量操作中下面调用且索引了两个文档(ID 1 - John Doe 和 ID 2 - Jane Doe):

curl -XPOST 'localhost:9200/customer/external/_bulk?pretty&pretty' -d'
{"index":{"_id":"1"}}
{"name": "John Doe" }
{"index":{"_id":"2"}}
{"name": "Jane Doe" }
'

这个例子使用一个批量操作更新了第一个文档(ID1),然后删除了第二个文档(ID2) :

curl -XPOST 'localhost:9200/customer/external/_bulk?pretty&pretty' -d'
{"update":{"_id":"1"}}
{"doc": { "name": "John Doe becomes Jane Doe" } }
{"delete":{"_id":"2"}}
'

请注意上面的删除操作,在它后面没有相关的源文档,因为删除操作只需要文档的 ID 来删除。

bulk API 以此按顺序执行所有的 action(动作)。如果一个单个的动作因任何原因而失败,它将继续处理它后面剩余的动作。当 bulk API 返回时,它将提供每个动作的状态(与发送的顺序相同),所以您可以检查是否一个指定的动作是不是失败了。

删除文档

curl -XDELETE 'localhost:9200/customer/external/2?pretty&pretty'

请看 Delete By Query API 以删除指定查询匹配到的所有文档。值得注意的是,它是删除一个完整的索引更有效的方式,而不是使用 Delete By Query API 来删除所有的文档。

更新记录

#更新文档
#更新我们先前的文档(ID 为 1),通过修改 name 字段的值为 “Jane Doe” : 
curl -XPOST 'localhost:9200/customer/external/1/_update?pretty&pretty' -d'
{
  "doc": { "name": "Jane Doe" }
}'
#更新我们先前的文档(ID 为 1),通过修改 name 字段的值为 “Jane Doe”,并且同时添加 age 字段 : 
curl -XPOST 'localhost:9200/customer/external/1/_update?pretty&pretty' -d'
{
  "doc": { "name": "Jane Doe", "age": 20 }
}'
#更新也是通过使用简单的简本来执行。这个例子演示了使用简本来将 age 加 5 : 
curl -XPOST 'localhost:9200/customer/external/1/_update?pretty&pretty' -d'
{
  "script" : "ctx._source.age += 5"
}'
#在上面的例子中,ctx._source 代表当前将被更新的源文档。

副本分片操作

# 查看副本分片信息
curl -XGET http://192.168.79.131:9200/shb01/_settings?pretty

#不存在索引shb03时可以指定副本和分片,如果shb03已经存在则只能修改副本
curl -XPUT http://192.168.79.131:9200/shb03-d'{"settings":{"number_of_shards":4,"number_of_replicas":2}}'

#在es中添加索引数据时不需要指定数据类型,es中有自动影射机制,字符串映射为string,数字映射为long。通过mappings可以指定数据类型是否存储等属性。
#查看mapping信息
curl -XGEThttp://192.168.79.131:9200/shb01/_mappings?pretty

分片查询

Es会将数据均衡的存储在分片中,我们可以指定es去具体的分片或节点钟查询从而进一步的实现es极速查询。

  1. randomizeacross shards: 随机选择分片查询数据,es的默认方式
  2. _local: 优先在本地节点上的分片查询数据然后再去其他节点上的分片查询,本地节点没有IO问题但有可能造成负载不均问题。数据量是完整的
  3. _primary:只在主分片中查询不去副本查,一般数据完整。
  4. _primary_first:优先在主分片中查,如果主分片挂了则去副本查,一般数据完整。
  5. _only_node:只在指定id的节点中的分片中查询,数据可能不完整。
  6. __prefer_node : 优先在指定你给节点中查询,一般数据完整。
  7. _shards : 在指定分片中查询,数据可能不完整
  8. _only_nodes : 可以自定义去指定的多个节点查询,es不提供此方式需要改源码。

上一篇:037.PGSQL-事务 savepoint 保存点、rollback to 回滚


下一篇:智能合约 solidity-TestContract.sol