ES 的 bulk
語法允許在一個請求中進行多個操作(create、index、update、delete),也就是可以在一次請求裡做很多事情
bulk 的請求模板
index
(最常用) : 如果文檔不存在就創建他,如果文檔存在就更新他create
: 如果文檔不存在就創建他,但如果文檔存在就返回錯誤
_id
值,他才能去判斷這個文檔是否存在update
: 更新一個文檔,如果文檔不存在就返回錯誤
_id
值,且後面文檔的格式和其他人不一樣delete
: 刪除一個文檔,如果要刪除的文檔 id 不存在,就返回錯誤
_id
,且後面不能帶一個 doc,因為沒意義,他是用 _id
去刪除文檔的_id
、_index
POST mytest/_bulk
{ action : { metadata } }
{ doc }
{ action : { metadata } }
{ doc }
....
具體實例
bulk請求
POST mytest/_bulk
//創建一筆數據
{ "create" : { "_id": 1 } }
{ "color": "create black" }
//創建一筆數據,因為id=1的文檔已經存在,所以會創建失敗
{ "create" : { "_id": 1 } }
{ "color": "create black2" }
//索引一筆數據
{ "index" : { "_id": 2 } }
{ "color": "index red" }
//索引一筆數據,但是index可以創建也可以更新,所以執行成功
{ "index" : { "_id": 2 } }
{ "color": "index red2" }
//索引一筆數據,不一定要設置id(index又能創建又能更新又不用設id,超好用)
{ "index": {} }
{ "color": "index blue" }
//刪除一筆文檔,注意delete後面不接一個doc
{ "delete" : { "_id": "2" } }
//找不到此id的文檔,刪除失敗
{ "delete" : { "_id": "2" } }
//更新一筆文檔,注意doc格式不太一樣
{ "update" : { "_id": 1 } }
{ "doc": { "color": "update green"} }
//更新一筆文檔,但因為此id的文檔不存在,所以更新失敗
{ "update" : { "_id": 100 } }
{ "doc": { "color": "update green2"} }
bulk 的返回結果
因為在 bulk 中,每個 action 的執行結果都是獨立的,所以有幾個 action,就會有幾個返回結果,返回結果如下
errors
,表示這一次 bulk 請求中,是否有 action 出錯了errors
這個值,如果是 false,表示這次 bulk 請求全部通過,就不用再一一去檢查是否有 action 出錯,但如果是 true,則必須去 items
一個一個檢查到底是哪個 action 出錯了items
是一個 array,裡面則放著每個 action 對應的結果,上面的請求執行了 9 個 action,所以返回結果的 items 就會有 9 個
items
的第一個結果就是請求時第一個 action 的執行結果
{
"took": 145,
"errors": true,
"items": [
{
"create": {
"_index": "mytest",
"_type": "_doc",
"_id": "1",
"result": "created",
"status": 201
}
},
{
"create": {
"_index": "mytest",
"_type": "_doc",
"_id": "1",
"status": 409,
"error": {
"type": "version_conflict_engine_exception",
"reason": "[1]: version conflict, document already exists (current version [1])",
"index_uuid": "PfdgdTyiRgaCIM6uKRQAPQ",
"shard": "0",
"index": "mytest"
}
}
},
{
"index": {
"_index": "mytest",
"_type": "_doc",
"_id": "2",
"result": "created",
"status": 201
}
},
{
"index": {
"_index": "mytest",
"_type": "_doc",
"_id": "2",
"result": "updated",
"status": 200
}
}
... 5 RESULTS REMOVED ...
]
}
使用 bulk 要注意的地方
127.0.0.1/_bulk
,那麼就是在整個 ES 的範圍中插入數據,因此在 metadata 中要指定插入的 index,優點是可以一次插入多筆數據到不同的索引
127.0.0.1/mytest/_bulk
,就不用在 metadata 再次指定要插入的 index,可以想像成是 _bulk
API幫我們自動填好了 metadata 的 _index
,很方便application/x-ndjson
\n
,如果是一般在 postman 寫請求不會有問題,但是如果是使用 curl
來發送請求,就要使用 --data-binary
,才會使每一句的結尾都是 \n
多大是太大了?
bulk
批量請求都需要由接收到請求的節點加載到內存中,因此該請求越大,其他請求所能獲得的內存就越少