注:此文檔僅適用于 Elasticsearch > 5.0 版本
Index API
index api
用于在指定的索引和類型下添加或修改文檔。例如:
PUT twitter/tweet/1
{
"user" : "kimchy",
"post_date" : "2009-11-15T14:12:12",
"message" : "trying out Elasticsearch"
}
路徑 twitter/tweet/1
中包含了三部分信息,其中,twitter
表示索引名稱,tweet
表示類型名稱,1
表示文檔的 id
,文檔的 id
是可選的。
如果 id
不存在,表示新增一個(gè)文檔,并為這個(gè)文檔分配一個(gè) id
。
如果 id
存在,并且這個(gè) id
對(duì)應(yīng)的文檔在 Elasticsearch 中存在,則表示更新文檔,這時(shí)的更新表示全量更新,直接替換。如果 id
對(duì)應(yīng)的文檔在 Elasticsearch 中不存在,則會(huì)在 Elasticsearch 中創(chuàng)建新的文檔,文檔的 id
為 path
上的 id
。
在 Elasticsearch 中,索引、類型、ID 組合定位一個(gè)文檔。也就是說(shuō),不同類型下,ID 是可以重復(fù)的。
Create API
Create API 也用于創(chuàng)建文檔,與 index API 不同,Create API只用于創(chuàng)建文檔,沒有更新文檔的功能。并且,Create API 必須提供 id
,當(dāng)相同id
的文檔已經(jīng)存在時(shí),Elasticsearch 會(huì)返回 409 Conflicat 響應(yīng)碼。
PUT twitter/tweet/1/_create
{
"user" : "kimchy",
"post_date" : "2009-11-15T14:12:12",
"message" : "trying out Elasticsearch"
}
Get API
GET API 非常簡(jiǎn)單,它通過(guò)索引名稱、類型名稱、ID這三個(gè)信息獲取制定文檔:
GET twitter/tweet/1
返回的信息中包含了文檔的一些元數(shù)據(jù),以及 _source
屬性。
{
"_index" : "twitter",
"_type" : "tweet",
"_id" : "1",
"_version" : 1,
"found": true,
"_source" : {
"user" : "kimchy",
"date" : "2009-11-15T14:12:12",
"likes": 0,
"message" : "trying out Elasticsearch"
}
}
如果將 GET 請(qǐng)求變成 DELETE 請(qǐng)求,則表示刪除文檔。
DELETE twitter/tweet/1
Update API
在 index API 中,我們已經(jīng)可以進(jìn)行更新文檔操作了。但是使用 index API 時(shí),更新操作是全量更新的,如果我只想更新文檔的一個(gè)字段,那么就需要使用 Update API 來(lái)進(jìn)行增量更新。
POST /website/blog/1/_update
{
"views": 1
}
樂觀并發(fā)控制
在數(shù)據(jù)庫(kù)中,我們一般使用事務(wù)來(lái)處理沖突的情況。在 Elasticsearch 中,我們一般使用樂觀鎖的方式來(lái)避免沖突。
在前面的例子中,我們可能注意到文檔都有一個(gè) _version
的元信息,這個(gè)信息表示文檔的版本號(hào),當(dāng)文檔被修改時(shí),版本號(hào)遞增。Elasticsearch 就是利用 _version
做的樂觀鎖。
在更新文檔時(shí),我們可以指定 _version
版本,
PUT twitter/tweet/1?version=2
{
"message" : "elasticsearch now has versioning support, double cool!"
}
上面的例子表示文檔只有版本號(hào)為 2
時(shí),更新才能成功。如果更新失敗,Elasticsearch 會(huì)返回 409 Conflict HTTP 響應(yīng)碼,以及一個(gè)錯(cuò)誤提示的相應(yīng)體。當(dāng)沖突發(fā)生時(shí),可以使用新的數(shù)據(jù)重新更新,或者將相關(guān)情況告訴用戶。
Bulk API
bulk API 允許在單個(gè)步驟中進(jìn)行多次 create
、 index
、 update
或 delete
請(qǐng)求。 如果你需要索引一個(gè)數(shù)據(jù)流比如日志事件,它可以排隊(duì)和索引數(shù)百或數(shù)千批次。
bulk 與其他請(qǐng)求的請(qǐng)求體格式不同,如下所示:
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"} }
這種格式類似一個(gè)有效的單行 JSON 文檔 流 ,它通過(guò)換行符(\n
)連接到一起。注意兩個(gè)要點(diǎn):
- 每行一定要以換行符(
\n
)結(jié)尾, 包括最后一行 。這些換行符被用作一個(gè)標(biāo)記,可以有效分隔行。 - 這些行不能包含未轉(zhuǎn)義的換行符,因?yàn)樗麄儗?huì)對(duì)解析造成干擾。這意味著這個(gè) JSON 不 能使用 pretty 參數(shù)打印。
delete
動(dòng)作不能有請(qǐng)求體,它后面跟著的是另外一個(gè)操作。
bulk 請(qǐng)求的每個(gè)子請(qǐng)求都是獨(dú)立執(zhí)行,因此某個(gè)子請(qǐng)求的失敗不會(huì)對(duì)其他子請(qǐng)求的成功與否造成影響。 如果其中任何子請(qǐng)求失敗,則返回值的最頂層的 error
標(biāo)志被設(shè)置為 true
,并且在相應(yīng)的請(qǐng)求報(bào)告出錯(cuò)誤明細(xì):
{
"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
}}
]
}
整個(gè)批量請(qǐng)求都需要由接收到請(qǐng)求的節(jié)點(diǎn)加載到內(nèi)存中,因此該請(qǐng)求越大,其他請(qǐng)求所能獲得的內(nèi)存就越少。 批量請(qǐng)求的大小有一個(gè)最佳值,大于這個(gè)值,性能將不再提升,甚至?xí)陆怠?但是最佳值不是一個(gè)固定的值。它完全取決于硬件、文檔的大小和復(fù)雜度、索引和搜索的負(fù)載的整體情況。一個(gè)好的批量大小在開始處理后所占用的物理大小約為 5-15 MB。
Scroll
scroll
查詢 可以用來(lái)對(duì) Elasticsearch 有效地執(zhí)行大批量的文檔查詢,而又不用付出深度分頁(yè)那種代價(jià)。
啟用游標(biāo)查詢可以通過(guò)在查詢的時(shí)候設(shè)置參數(shù) scroll
的值為我們期望的游標(biāo)查詢的過(guò)期時(shí)間。 游標(biāo)查詢的過(guò)期時(shí)間會(huì)在每次做查詢的時(shí)候刷新,所以這個(gè)時(shí)間只需要足夠處理當(dāng)前批的結(jié)果就可以了,而不是處理查詢結(jié)果的所有文檔的所需時(shí)間。 這個(gè)過(guò)期時(shí)間的參數(shù)很重要,因?yàn)楸3诌@個(gè)游標(biāo)查詢窗口需要消耗資源,所以我們期望如果不再需要維護(hù)這種資源就該早點(diǎn)兒釋放掉。 設(shè)置這個(gè)超時(shí)能夠讓 Elasticsearch 在稍后空閑的時(shí)候自動(dòng)釋放這部分資源。
GET /old_index/_search?scroll=1m
{
"query": { "match_all": {}},
"sort" : ["_doc"],
"size": 1000
}
size
指的是每次返回的文檔個(gè)數(shù),這個(gè)字段作用于每個(gè)分片,實(shí)際上每次返回的文檔個(gè)數(shù)最大為 size * number_of_primary_shards
。
這個(gè)查詢的返回結(jié)果包括一個(gè)字段 _scroll_id
, 它是一個(gè)base64編碼的長(zhǎng)字符串。 現(xiàn)在我們能傳遞字段 _scroll_id
到 _search/scroll
查詢接口獲取下一批結(jié)果:
GET /_search/scroll
{
"scroll": "1m",
"scroll_id" : "cXVlcnlUaGVuRmV0Y2g7NTsxMDk5NDpkUmpiR2FjOFNhNnlCM1ZDMWpWYnRROzEwOTk1OmRSamJHYWM4U2E2eUIzVkMxalZidFE7MTA5OTM6ZFJqYkdhYzhTYTZ5QjNWQzFqVmJ0UTsxMTE5MDpBVUtwN2lxc1FLZV8yRGVjWlI2QUVBOzEwOTk2OmRSamJHYWM4U2E2eUIzVkMxalZidFE7MDs="
}
參考資料: