1. 程式人生 > >Elasticsearch使用MultiGet批量獲取文件與使用Bulk批量操作

Elasticsearch使用MultiGet批量獲取文件與使用Bulk批量操作

Multi Get 批量獲取

Multi Get API可以通過索引名、型別名、文件id一次得到一個文件集合,文件可以來自同一個索引庫,也可以來自不同的索引庫。

GET /_mget
{
  "docs":[
     {
        "_index": "lib",
        "_type": "user",
        "_id": "1"
     },
     {
        "_index": "lib",
        "_type": "user",
        "_id": "2"
     },
     {
        "_index": "lib"
, "_type": "user", "_id": "3" } ] } //可以指定具體的欄位 GET /_mget { "docs":[ { "_index": "lib", "_type": "user", "_id": "1", "_source": "interests" }, { "_index": "lib", "_type": "user", "_id": "2", "_source"
: {"age","interests"} } ] } //獲取同索引同類型下的不同文件 GET /lib/user/_mget { "docs":[ { "_id": "1" }, { "_type": "user", //若是指定索引和型別必須和請求頭上的保持一致,否者將會報錯。 "_id": "2" } ] } //也可以使用下面這種更為簡化的寫法 GET /lib/user/_mget { "ids":["1","2"] }
Bulk 批量操作

bulk的格式:
{action:{metadata}}\n
{requstbody}\n (請求體)

  • action:(行為),包含create(文件不存在時建立)、update(更新文件)、index(建立新文件或替換已用文件)、delete(刪除一個文件)。
    create和index的區別:如果資料存在,使用create操作失敗,會提示文件已存在,使用index則可以成功執行。
  • metadata:(行為操作的具體索引資訊),需要指明資料的_index、_type、_id。

示例:

{"delete":{"_index":"lib","_type":"user","_id":"1"}}

批量新增

POST /lib2/books/_bulk
{"index":{"_id":1}}  \\行為:索引資訊
{"title":"Java","price","55"} \\請求體
{"index":{"_id":2}}
{"title":"Html5","price","45"}
{"index":{"_id":3}}
{"title":"Php","price","35"}`
{"index":{"_id":4}}
{"title":"Python","price","50"}

//返回結果
{
  "took": 60,
  "error": false //請求是否出錯,返回false、具體的錯誤
  "items": [
     //操作過的文件的具體資訊
     {
        "index":{
           "_index": "lib",
           "_type": "user",
           "_id": "1",
           "_version": 1,
           "result": "created", //返回請求結果
           "_shards": {
              "total": 1,
              "successful": 1,
              "failed": 0
           },
           "_seq_no": 0,
           "_primary_trem": 1
           "status": 200
        }
    }, 
    ... 
  ]
}

批量刪除
刪除的批量操作不需要請求體

POST /lib/books/_bulk
{"delete":{"_index":"lib","_type":"books","_id":"4"}} //刪除的批量操作不需要請求體
{"create":{"_index":"tt","_type":"ttt","_id":"100"}}
{"name":"lisi"} //請求體
{"index":{"_index":"tt","_type":"ttt"}} //沒有指定_id,elasticsearch將會自動生成_id
{"name":"zhaosi"} //請求體
{"update":{"_index":"lib","_type":"books","_id":"4"}} //更新動作不能缺失_id,文件不存在更新將會失敗
{"doc":{"price":58}} //請求體

bluk一次最大處理多少資料量
bulk會將要處理的資料載入記憶體中,所以資料量是有限的,最佳的資料兩不是一個確定的資料,它取決於你的硬體,你的文件大小以及複雜性,你的索引以及搜尋的負載。

一般建議是1000-5000個文件,大小建議是5-15MB,預設不能超過100M,可以在es的配置檔案(即$ES_HOME下的config下的elasticsearch.yml)中,bulk的執行緒池配置是核心數+1。

bulk批量操作的json格式解析
bulk的格式:
{action:{metadata}}\n
{requstbody}\n (請求體)

  1. 不用將其轉換為json物件,直接按照換行符切割json,記憶體中不需要json文字的拷貝。
  2. 對每兩個一組的json,讀取meta,進行document路由。
  3. 直接將對應的json傳送到node上。

為什麼不使用如下格式:

[{"action":{},"data":{}}]

這種方式可讀性好,但是內部處理就麻煩;耗費更多記憶體,增加java虛擬機器開銷:

  1. 將json陣列解析為JSONArray物件,在記憶體中就需要有一份json文字的拷貝,寧外好友一個JSONArray物件。
  2. 解析json數組裡的每個json,對每個請求中的document進行路由。
  3. 為路由到同一個shard上的多個請求,建立一個請求陣列。
  4. 將這個請求陣列序列化。