取得多個文檔
使用 multi-get 或者 mget
API 來將這些檢索請求放在一個請求中,將比逐個文檔請求更快地檢索到全部文檔。mget
API 要求有一個 docs
數組作為參數,每個 元素包含需要檢索文檔的元數據, 包括 _index
、 _type
和 _id
。如果你想檢索一個或者多個特定的字段,那么你可以通過 _source
參數來指定這些字段的名字:
GET /_mget { "docs" : [ { "_index" : "website", "_type" : "blog", "_id" : 2 }, { "_index" : "website", "_type" : "pageviews", "_id" : 1, "_source": "views" } ] }
響應體:
{ "docs" : [ { "_index" : "website", "_id" : "2", "_type" : "blog", "found" : true, "_source" : { "text" : "This is a piece of cake...", "title" : "My first external blog entry" }, "_version" : 10 }, { "_index" : "website", "_id" : "1", "_type" : "pageviews", "found" : true, "_version" : 2, "_source" : { "views" : 2 } } ] }
bulk
與其他的請求體格式稍有不同,如下所示:
{ action: { metadata }}\n { request body }\n { action: { metadata }}\n { request body }\n ...
這種格式類似一個有效的單行 JSON 文檔 流 ,它通過換行符(\n
)連接到一起。注意兩個要點:
- 每行一定要以換行符(
\n
)結尾, 包括最后一行 。這些換行符被用作一個標記,可以有效分隔行。 - 這些行不能包含未轉義的換行符,因為他們將會對解析造成干擾。這意味着這個 JSON 不 能使用 pretty 參數打印。
action/metadata
行指定 哪一個文檔 做 什么操作 。
metadata
應該 指定被索引、創建、更新或者刪除的文檔的 _index
、 _type
和 _id
。
例如,一個 delete
請求看起來是這樣的:
{ "delete": { "_index": "website", "_type": "blog", "_id": "123" }}
request body
行由文檔的 _source
本身組成--文檔包含的字段和值。它是 index
和 create
操作所必需的,這是有道理的:你必須提供文檔以索引。
它也是 update
操作所必需的,並且應該包含你傳遞給 update
API 的相同請求體: doc
、 upsert
、 script
等等。 刪除操作不需要 request body
行。
{ "create": { "_index": "website", "_type": "blog", "_id": "123" }} { "title": "My first blog post" }
如果不指定 _id
,將會自動生成一個 ID :
{ "index": { "_index": "website", "_type": "blog" }} { "title": "My second blog post" }
為了把所有的操作組合在一起,一個完整的 bulk
請求 有以下形式:
POST /_bulk { "delete": { "_index": "website", "_type": "blog", "_id": "123" }} { "create": { "_index": "website", "_type": "blog", "_id": "123" }} { "title": "My first blog post" } { "index": { "_index": "website", "_type": "blog" }} { "title": "My second blog post" } { "update": { "_index": "website", "_type": "blog", "_id": "123", "_retry_on_conflict" : 3} } { "doc" : {"title" : "My updated blog post"} }
這個 Elasticsearch 響應包含 items
數組, 這個數組的內容是以請求的順序列出來的每個請求的結果。
{ "took": 4, "errors": false, "items": [ { "delete": { "_index": "website", "_type": "blog", "_id": "123", "_version": 2, "status": 200, "found": true }}, { "create": { "_index": "website", "_type": "blog", "_id": "123", "_version": 3, "status": 201 }}, { "create": { "_index": "website", "_type": "blog", "_id": "EiwfApScQiiy7TIKFxRCTw", "_version": 1, "status": 201 }}, { "update": { "_index": "website", "_type": "blog", "_id": "123", "_version": 4, "status": 200 }} ] }
每個子請求都是獨立執行,因此某個子請求的失敗不會對其他子請求的成功與否造成影響。 如果其中任何子請求失敗,最頂層的 error
標志被設置為 true
,並且在相應的請求報告出錯誤明細:
POST /_bulk { "create": { "_index": "website", "_type": "blog", "_id": "123" }} { "title": "Cannot create - it already exists" } { "index": { "_index": "website", "_type": "blog", "_id": "123" }} { "title": "But we can update it" }
在響應中,我們看到 create
文檔 123
失敗,因為它已經存在。但是隨后的 index
請求,也是對文檔 123
操作,就成功了:
{ "took": 3, "errors": true,
"items": [ { "create": { "_index": "website", "_type": "blog", "_id": "123", "status": 409,
"error": "DocumentAlreadyExistsException
[[website][4] [blog][123]: document already exists]" }}, { "index": { "_index": "website", "_type": "blog", "_id": "123", "_version": 5, "status": 200
}} ] }
這也意味着 bulk
請求不是原子的: 不能用它來實現事務控制。每個請求是單獨處理的,因此一個請求的成功或失敗不會影響其他的請求。