1. 程式人生 > 程式設計 >999 - Elasticsearch 快速上手

999 - Elasticsearch 快速上手

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?v

epoch      timestamp cluster       status node.total node.data shards pri relo init unassign pending_tasks max_task_wait_time active_shards_percent
1555378987 01:43:07  elasticsearch green           1         1      4   4    0    0        0             0                  -                100.0%
複製程式碼

節點資訊

列出所有節點。

GET /_cat/nodes?v

ip        heap.percent ram.percent cpu load_1m load_5m load_15m node.role master name
127.0.0.1           49          73  11                          mdi       *      m9Y7FJV
複製程式碼

索引資訊

列出所有索引。

GET /_cat/indices?v

health status index                           uuid                   pri rep docs.count docs.deleted store.size pri.store.size
green  open   .monitoring-es-6-2019.04.16     IND0TKuCQsyHTH2FDE1zdg   1   0       5478           36      2.7mb          2.7mb
green  open   .kibana_1                       XTsD7vQ7QbukbJpFlkfLQQ   1   0          4            0     14.4kb         14.4kb
green  open   .kibana_task_manager            0G59n4AWQzSxJ6YSHBDPnA   1   0          2            0     12.5kb         12.5kb
green  open   .monitoring-kibana-6-2019.04.16 -SZdui1tTw-srkqmUxzQHw   1   0        684            0    309.2kb        309.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","_primary_term" : 1,"found" : true,"_source" : {
    "name" : "Put Add"
  }
}
複製程式碼

使用POST新增:自動生成id

POST /customer/_doc?pretty
{
  "name": "Post Add"
}
複製程式碼

響應

{
  "_index" : "customer","_id" : "RYeuJGoB_H2WuLZOyvLU","_primary_term" : 1
}
複製程式碼

更新檔案

Elasticsearch實際上並不是更新檔案,而是建立新檔案。

使用PUT更新:ID相同時會替換,也就相當於更新。

PUT /customer/_doc/1?pretty
{
  "name": "PUT Update"
}
複製程式碼

響應:_version、result改變了。

{
  "_index" : "customer","_version" : 2,"result" : "updated","_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": "[email protected]","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"
        }
      },"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
}
複製程式碼