999|999 - Elasticsearch 快速上手

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

  • 检查集群、节点、索引的健康、状态以及统计信息。
  • 管理你的集群、节点和索引数据、元数据。
  • 对索引进行CRUD。
  • 执行分页、排序、过滤、脚本编写、聚合以及其他高级搜索。
Elasticsearch请求格式: ///
文档说明
  • 学习的是Elasticsearch v6.7.1。
  • 示例都是用的Kibana,如果不明白Kibana可以看我的或者官网以及其他人的Kibana教程,只需要看DevTools如何使用暂时就够了,也可以用Postman、RestletClient、curl等,能发送REST请求的都可以。
快速入门示例 集群信息
集群健康值:
  • green:一切正常。(集群功能齐全)
  • yellow:所有数据可用,一些副本尚未分配。(集群功能齐全)
  • red:一些数据由于某种原因不可用。(集群部分功能可用)
注意:状态为red时仍然提供搜索服务(在可用的分片中搜索),但你需要尽快的去修复它。
GET /_cat/health?vepochtimestamp clusterstatus node.total node.data shards pri relo init unassign pending_tasks max_task_wait_time active_shards_percent 1555378987 01:43:07elasticsearch green11440000-100.0%

节点信息
列出所有节点。
GET /_cat/nodes?vipheap.percent ram.percent cpu load_1m load_5m load_15m node.role master name 127.0.0.1497311mdi*m9Y7FJV

索引信息
列出所有索引。
GET /_cat/indices?vhealth status indexuuidpri rep docs.count docs.deleted store.size pri.store.size greenopen.monitoring-es-6-2019.04.16IND0TKuCQsyHTH2FDE1zdg105478362.7mb2.7mb greenopen.kibana_1XTsD7vQ7QbukbJpFlkfLQQ104014.4kb14.4kb greenopen.kibana_task_manager0G59n4AWQzSxJ6YSHBDPnA102012.5kb12.5kb greenopen.monitoring-kibana-6-2019.04.16 -SZdui1tTw-srkqmUxzQHw106840309.2kb309.2kb

创建索引
创建一个索引:名叫customer,2个分片,0副本。
# PUT /customer # PUT /customer?pretty PUT /customer?pretty { "settings": { "number_of_shards": 2, "number_of_replicas": 0 } }

注意:默认是5个分片1个副本,如果只有一个节点,副本分片就会没有地方分配,集群状态就会为YELLOW。
解释一下pretty(pretty-printed),直接看示例

添加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”。

另外,在新增文档时可以不提前创建好索引与类型,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更新

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?pretty DELETE /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"}}

批量操作不会因为其中一个失败中断后续的操作。结束后会按顺序返回响应信息。

示例:增删改报错不会中断,操作类型写错会忽略执行。
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

    注意@必须要有,否则也会报错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:要查询的字段

sort:用来排序的字段,asc升序,desc倒序

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

返回结果中的字段:

took:ES执行查询的时间,毫秒

timed_out:告诉我们搜索是否超时

_shards:搜索了多少个分片,以及搜索成功/失败的个数。

hits:查询结果

hits.total:符合搜索条件的总数

hits.hits:搜索结果

hits.hits.sort:用来排序的字段,如果没有指定则按分数排序,就不会有这一部分。

hits.max_scorehits.hits._score:相关性分数,分数越高表明与搜索条件越接近。

Request Body Search
示例

match_all:match_all查询,查询所有字段

sort:用来排序的字段。

from:从哪里开始,默认从0开始。

size:查多少个,默认10个。

_source: 指定返回的字段。

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

match

查询address包含milllane的。

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

match_phrase

查询address包含mill lane的。
GET /bank/_search { "query": { "match_phrase": { "address": "mill lane" } } }

bool

bool查询的好处在于可以组合多个条件(match、match_phrase等)。

must:满足所有匹配条件。

should:满足其中一个匹配条件。

must_not:必须不满足条件。

filter:过滤内容,并且不进行相关性算分。

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 } } } } } }

聚合查询

示例一:聚合示例,按state分组,返回前100条聚合结果。

说明:外边一个size设为0,是为了不返回文档只返回聚合结果;field字段下面的size表示terms聚合返回多少条聚合结果,默认10条。

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 }

【999|999 - Elasticsearch 快速上手】示例四:按照年龄分区间,然后再按照性别分组,最后求出每组的平均余额。
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 }

    推荐阅读