Elasticsearch - 文檔的基本操作

注:此文檔僅適用于 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)建新的文檔,文檔的 idpath 上的 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)行多次 createindexupdatedelete 請(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="
}

參考資料:

  1. Elasticsearch: 權(quán)威指南
  2. Elasticsearch 官方文檔
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,156評(píng)論 6 531
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 98,401評(píng)論 3 415
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人,你說(shuō)我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,069評(píng)論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我,道長(zhǎng),這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,873評(píng)論 1 309
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 71,635評(píng)論 6 408
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 55,128評(píng)論 1 323
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼。 笑死,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,203評(píng)論 3 441
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 42,365評(píng)論 0 288
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 48,881評(píng)論 1 334
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 40,733評(píng)論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 42,935評(píng)論 1 369
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,475評(píng)論 5 358
  • 正文 年R本政府宣布,位于F島的核電站,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 44,172評(píng)論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,582評(píng)論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,821評(píng)論 1 282
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 51,595評(píng)論 3 390
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 47,908評(píng)論 2 372

推薦閱讀更多精彩內(nèi)容