1. 程式人生 > 其它 >ElasticSearch 常用API

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":"[email protected]","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":"[email protected]","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不提供此方式需要改原始碼。