批量查詢 _mget
使用批量查詢的好處在於將多次網絡請求合併成一個,大大減少了網絡消耗,提升ES查詢效率。
具體API如下:
GET /_mget
{
"docs":[
{
"_index":"employee",
"_type":"_doc",
"_id":"1"
},{
"_index":"employee",
"_type":"_doc",
"_id":"2"
}
]
}
如果都是查詢同樣的 index 可以將其提取到請求路徑中,像這樣:
GET /employee/_mget
{
"docs":[
{
"_type":"_doc",
"_id":"1"
},{
"_type":"_doc",
"_id":"2"
}
]
}
如果 index 和 type 都一樣那我們還可以簡寫成這樣:
GET /employee/_doc/_mget
{
"ids":["1","2"]
}
這裏三種方式的查詢結果是一樣的。
這裏注意,如果多個查詢條件中某一個條件不存在,結果還是會正常返回,僅僅對未查到的那個數據的結果位置中的 fount 字段值爲 false,像這樣:
"docs" : [
.... ,
{
"_index" : "employee",
"_type" : "_doc",
"_id" : "4",
"found" : false
}, ....
]
批量寫 _bulk
_bulk API允許我們在一次請求中執行多次 create、index、update、delete等操作。
通常還是批量寫入較多,比如日誌寫入ES就可以使用 _bulk,API 語法如下:
{ action: { metadata }}\n
{ request body }\n
{ action: { metadata }}\n
{ request body }\n
......
這裏需要注意:
- action 只能爲 create、index、update、delete,各選項的意義如下:
- create 當且僅當文檔不存在時,創建新文檔
- index 創建一個新文檔或者是全量更新舊文檔
- update 局部更新文檔
- delete 刪除文檔
- metadata 用來設置像這樣的元數據:_index、_type、_id
- request body 可以理解爲 _source 的內容
- 每行一定要以換行符(\n)結尾, 包括最後一行 。這些換行符被用作一個標記,可以有效分隔行
- 這些行不能包含未轉義的換行符,因爲他們將會對解析造成干擾。這意味着這個 JSON 不 能使用 pretty 參數打印。
這種每條命令以換行符結尾的格式使得ES可以無需做過多解析就可以將命令分發到各自對應的節點執行。
這裏我們通過 _bulk 來做一次批量新增:
POST _bulk
{"create":{"_index":"technology","_type":"_doc","_id":"1"}}
{"name":"Java"}
{"create":{"_index":"technology","_type":"_doc","_id":"2"}}
{"name":"Javascript"}
{"create":{"_index":"technology","_type":"_doc","_id":"3"}}
{"name":"css"}
返回結果如下:
{
"took" : 141,
"errors" : false,
"items" : [
{
"create" : {
"_index" : "technology",
"_type" : "_doc",
"_id" : "1",
"_version" : 1,
"result" : "created",
"_shards" : {
"total" : 2,
"successful" : 2,
"failed" : 0
},
"_seq_no" : 0,
"_primary_term" : 1,
"status" : 201
}
},
{
"create" : {
"_index" : "technology",
"_type" : "_doc",
"_id" : "2",
"_version" : 1,
"result" : "created",
"_shards" : {
"total" : 2,
"successful" : 2,
"failed" : 0
},
"_seq_no" : 1,
"_primary_term" : 1,
"status" : 201
}
},
{
"create" : {
"_index" : "technology",
"_type" : "_doc",
"_id" : "3",
"_version" : 1,
"result" : "created",
"_shards" : {
"total" : 2,
"successful" : 2,
"failed" : 0
},
"_seq_no" : 0,
"_primary_term" : 1,
"status" : 201
}
}
]
}
這些字段都不陌生,就不多解釋了。
index 和 update 和 create 操作類似,而 delete 動作不能有請求體,所以這裏在給一個 delete 的實例:
POST _bulk
{"delete":{"_index":"technology","_type":"_doc","_id":"1"}}
{"delete":{"_index":"technology","_type":"_doc","_id":"2"}}
返回結果與上面一樣,只是 result 的值爲 deleted。
和 _mget API一樣, _bulk 的多個操作中若某一個失敗不會影響其他命令執行,它們是互相獨立的。
注意
雖然批量操作可以提升性能,但不是說可以將無限多的命令通過 _bulk API一次執行,當執行的命令條數到達一定數量級的時候,性能反而會下降,所以這裏我們需要自己測試出機器的最佳性能的所執行的命令條數。並且還需注意 _source 字段的數據量不要過大,否則也會有同樣的問題。