Elasticsearch REST API

Elasticsearch提供了全面强大的REST API:

  • 检查集群、节点、索引的健康、状态以及统计信息。
  • 管理你的集群、节点和索引数据、元数据。
  • 对索引进行CRUD。
  • 执行分页、排序、过滤、脚本编写、聚合以及其他高级搜索。

Elasticsearch请求格式:<HTTP Verb> /<Index>/<Type>/<ID>

文档说明

  • 学习的是Elasticsearch v6.7.1。
  • 示例都是用的Kibana,如果不明白Kibana可以看我的或者官网以及其他人的Kibana教程,只需要看DevTools如何使用暂时就够了,也可以用Postman、RestletClient、curl等,能发送REST请求的都可以。

快速入门示例

集群信息

集群健康值:

  • green:一切正常。(集群功能齐全)
  • yellow:所有数据可用,一些副本尚未分配。(集群功能齐全)
  • red:一些数据由于某种原因不可用。(集群部分功能可用)

注意:状态为red时仍然提供搜索服务(在可用的分片中搜索),但你需要尽快的去修复它。

GET /_cat/health?vepoch      timestamp cluster       status node.total node.data shards pri relo init unassign pending_tasks max_task_wait_time active_shards_percent1555378987 01:43:07  elasticsearch green           1         1      4   4    0    0        0             0                  -                100.0%

节点信息

列出所有节点。

GET /_cat/nodes?vip        heap.percent ram.percent cpu load_1m load_5m load_15m node.role master name127.0.0.1           49          73  11                          mdi       *      m9Y7FJV

索引信息

列出所有索引。

GET /_cat/indices?vhealth status index                           uuid                   pri rep docs.count docs.deleted store.size pri.store.sizegreen  open   .monitoring-es-6-2019.04.16     IND0TKuCQsyHTH2FDE1zdg   1   0       5478           36      2.7mb          2.7mbgreen  open   .kibana_1                       XTsD7vQ7QbukbJpFlkfLQQ   1   0          4            0     14.4kb         14.4kbgreen  open   .kibana_task_manager            0G59n4AWQzSxJ6YSHBDPnA   1   0          2            0     12.5kb         12.5kbgreen  open   .monitoring-kibana-6-2019.04.16 -SZdui1tTw-srkqmUxzQHw   1   0        684            0    309.2kb        309.2kb

创建索引

创建一个索引:名叫customer,2个分片,0副本。

# PUT /customer# PUT /customer?prettyPUT /customer?pretty{  "settings": {    "number_of_shards": 2,    "number_of_replicas": 0  }}

注意:默认是5个分片1个副本,如果只有一个节点,副本分片就会没有地方分配,集群状态就会为YELLOW。

解释一下pretty(pretty-printed),直接看示例<br/>
添加pretty时:

{"acknowledged": true,"shards_acknowledged": true,"index": "customer"}

没有添加pretty时:

{"acknowledged":true,"shards_acknowledged":true,"index":"customer"}

删除索引

删除customer索引。

DELETE /customer?pretty

新增文档

使用PUT新增:id为1,name字段值为“Put Add”。<br/>
另外,在新增文档时可以不提前创建好索引与类型,elasticsearch会自动帮你创建。

PUT /customer/_doc/1?pretty{  "name": "Put Add"}

响应

{  "_index" : "customer",  "_type" : "_doc",  "_id" : "1",  "_version" : 1,  "result" : "created",  "_shards" : {    "total" : 1,    "successful" : 1,    "failed" : 0  },  "_seq_no" : 0,  "_primary_term" : 1}

查询刚才新增的数据

GET /customer/_doc/1?pretty{  "_index" : "customer",  "_type" : "_doc",  "_id" : "1",  "_version" : 1,  "_seq_no" : 0,  "_primary_term" : 1,  "found" : true,  "_source" : {    "name" : "Put Add"  }}

使用POST新增:自动生成id

POST /customer/_doc?pretty{  "name": "Post Add"}

响应

{  "_index" : "customer",  "_type" : "_doc",  "_id" : "RYeuJGoB_H2WuLZOyvLU",  "_version" : 1,  "result" : "created",  "_shards" : {    "total" : 1,    "successful" : 1,    "failed" : 0  },  "_seq_no" : 0,  "_primary_term" : 1}

更新文档

Elasticsearch实际上并不是更新文档,而是创建新文档。

使用PUT更新:ID相同时会替换,也就相当于更新。

PUT /customer/_doc/1?pretty{  "name": "PUT Update"}

响应:_version、result改变了。

{  "_index" : "customer",  "_type" : "_doc",  "_id" : "1",  "_version" : 2,  "result" : "updated",  "_shards" : {    "total" : 1,    "successful" : 1,    "failed" : 0  },  "_seq_no" : 1,  "_primary_term" : 1}

Post更新<br/>
1.更新字段

POST /customer/_doc/1/_update?pretty{  "doc": {    "name": "Post Update"  }}

2.更新的同时,新增一个字段。

POST /customer/_doc/1/_update?pretty{  "doc": {    "name": "Baozi",    "age": "21"  }}

3.使用脚本更新,将年龄增加5岁

POST /customer/_doc/1/_update?pretty{  "script": "ctx._source.age += 5"}

删除文档

DELETE /customer/_doc/1?prettyDELETE /customer/_doc/RYeuJGoB_H2WuLZOyvLU?pretty

批量操作

批量操作类型:

  • index:不存在就创建,已存在就更新
  • create:创建
  • delete:删除
  • update:更新

创建两个文档。

POST /customer/_doc/_bulk?pretty{"index":{"_id":"1"}}{"name":"Baozi1"}{"index":{"_id":"2"}}{"name":"Baozi2"}

更新文档1,删除文档2

POST /customer/_doc/_bulk?pretty{"update":{"_id":"1"}}{"doc":{"name":"Baozi1 Updated"}}{"delete":{"_id":"2"}}

批量操作不会因为其中一个失败中断后续的操作。结束后会按顺序返回响应信息。<br/>
示例:增删改报错不会中断,操作类型写错会忽略执行。

POST /customer/_doc/_bulk?pretty{"index":{"_id":"1"}}{"name":"Baozi1"}{"create":{"_id":"1"}}{"name":"Baozi1"}{"indexed":{"_id":"2"}}{"name":"Baozi2"}{"update":{"_id":"10000"}}{"doc":{"name":"Baozi10000"}}{"delete":{"_id":"100000"}}{"delete":{"_id":"100001"}}

快速入门查询示例

导入数据

使用官方提供的样本数据,格式:

{    "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"}
  • 将数据复制到文件account.json,之后在文件末尾新起一空行,否则报错bulk request must be terminated by newline
  • 创建索引
PUT /bank?pretty{  "settings": {    "number_of_shards": 2,    "number_of_replicas": 0  }}
  • 导入到ES<br/>

注意@必须要有,否则也会报错bulk request must be terminated by newline

$ curl -H "Content-Type: application/json" -XPOST "localhost:9200/bank/_doc/_bulk?pretty&refresh" --data-binary "@你的文件路径"

URI Search

q:要查询的字段<br/>
sort:用来排序的字段,asc升序,desc倒序<br/>

GET /bank/_search?q=*&sort=account_number:asc&pretty

返回结果中的字段:<br/>
took:ES执行查询的时间,毫秒<br/>
timed_out:告诉我们搜索是否超时<br/>
_shards :搜索了多少个分片,以及搜索成功/失败的个数。<br/>
hits:查询结果<br/>
hits.total:符合搜索条件的总数<br/>
hits.hits:搜索结果<br/>
hits.hits.sort:用来排序的字段,如果没有指定则按分数排序,就不会有这一部分。<br/>
hits.max_scorehits.hits._score:相关性分数,分数越高表明与搜索条件越接近。<br/>

Request Body Search

示例<br/>
match_all:match_all查询,查询所有字段<br/>
sort:用来排序的字段。<br/>
from:从哪里开始,默认从0开始。<br/>
size:查多少个,默认10个。<br/>
_source: 指定返回的字段。<br/>

GET /bank/_search{  "query": {"match_all": {}},  "sort": [    {      "account_number":"asc"    }  ],  "from": 10,  "size": 2,  "_source": ["account_number","balance"]}

match<br/>
查询address包含milllane的。<br/>
提示:ES存数据时会将mill lane分成milllane做一个分词,想要查询必须包含mill lane可以看下一条match_phrase的示例。

GET /bank/_search{  "query": {    "match": {      "address": "mill lane"    }  }}

match_phrase<br/>
查询address包含mill lane的。

GET /bank/_search{  "query": {    "match_phrase": {      "address": "mill lane"    }  }}

bool<br/>
bool查询的好处在于可以组合多个条件(match、match_phrase等)。<br/>
must:满足所有匹配条件。<br/>
should:满足其中一个匹配条件。<br/>
must_not:必须不满足条件。<br/>
filter:过滤内容,并且不进行相关性算分。<br/>

must:查询同时包含milllane的address。

GET /bank/_search{  "query": {    "bool": {      "must": [        {          "match": {            "address": "mill"          }        },        {          "match": {            "address": "lane"          }        }      ]    }  }}

should:查询包含milllane的address。

GET /bank/_search{  "query": {    "bool": {      "should": [        {          "match": {            "address": "mill"          }        },        {          "match": {            "address": "lane"          }        }      ]    }  }}

must_not: 查询不包含

GET /bank/_search{  "query": {    "bool": {      "must_not": [        {          "match": {            "address": "mill"          }        },        {          "match": {            "address": "lane"          }        }      ]    }  }}

组合match、must_not等:查询40岁并且不居住在ID(Idaho的缩写)的人。

GET /bank/_search{  "query": {    "bool": {      "must": [        {          "match": {            "age": "40"          }        }      ],      "must_not": [        {          "match": {            "state": "ID"          }        }      ]    }  }}

filter:对地址包含milllane的,进行过滤,取余额大于30000的。

GET /bank/_search{  "query": {    "bool": {      "must": [        {          "match": {            "address": "mill lane"          }        }      ],      "filter": {        "range": {          "balance": {            "gte": 30000          }        }      }    }  }}

聚合查询<br/>
示例一:聚合示例,按state分组,返回前100条聚合结果。<br/>
说明:外边一个size设为0,是为了不返回文档只返回聚合结果;field字段下面的size表示terms聚合返回多少条聚合结果,默认10条。<br/>

GET /bank/_search{  "aggs": {    "group_by_state": {      "terms": {        "field": "state.keyword",        "size": 100      }    }  },   "size": 0}

示例二:嵌套聚合,在上一个示例的基础上,计算每个州的平均余额。

GET /bank/_search{  "aggs": {    "group_by_state": {      "terms": {        "field": "state.keyword",        "size": 100      },      "aggs": {        "average_balance": {          "avg": {            "field": "balance"          }        }      }    }  },  "size": 0}

示例三:聚合排序,接着上一个示例,按照平均余额排序。

GET /bank/_search{  "aggs": {    "group_by_state": {      "terms": {        "field": "state.keyword",        "size": 100,        "order": {          "average_balance": "desc"        }      },      "aggs": {        "average_balance": {          "avg": {            "field": "balance"          }        }      }    }  },  "size": 0}

示例四:按照年龄分区间,然后再按照性别分组,最后求出每组的平均余额。

GET /bank/_search{  "aggs": {    "group_by_age": {      "range": {        "field": "age",        "ranges": [          {            "from": 20,            "to": 29          },          {            "from": 30,            "to": 39          },          {            "from": 40,            "to": 49          }        ]      },      "aggs": {        "group_by_gender": {          "terms": {            "field": "gender.keyword"          },          "aggs": {            "average_balance": {              "avg": {                "field": "balance"              }            }          }        }      }    }  },  "size": 0}