ElasticSearch基本相關(guān)概念描述

ElasticSearch版本2.4.2,新版本有待學(xué)習(xí)

什么是文檔寄摆?

在大多數(shù)應(yīng)用中蒸眠,多數(shù)實(shí)體或?qū)ο罂梢员恍蛄谢癁榘I值對的Json對象,一個 *鍵* 可以是一個字段或字段名稱窿凤,一個 *值* 可以是一個object:
{
    "name":         "John Smith",
    "age":          42,
    "confirmed":    true,
    "join_date":    "2014-06-01",
    "home": {
        "lat":      51.5,
        "lon":      0.1
    },
    "accounts": [
        {
            "type": "facebook",
            "id":   "johnsmith"
        },
        {
            "type": "twitter",
            "id":   "johnsmith"
        }
    ]
}

通常情況下仅偎,我們使用的術(shù)語 對象 和 文檔 是可以互相替換的。不過雳殊,有一個區(qū)別: 一個對象僅僅是類似于 hash 橘沥、 hashmap 、字典或者關(guān)聯(lián)數(shù)組的 JSON 對象夯秃,對象中也可以嵌套其他的對象座咆。 對象可能包含了另外一些對象。在 Elasticsearch 中仓洼,術(shù)語 文檔 有著特定的含義介陶。它是指最頂層或者根對象, 這個根對象被序列化成 JSON 并存儲到 Elasticsearch 中,指定了唯一 ID色建。

字段名稱可以使用任何合法的字符串哺呜,不可以使用英文句號(.)

文檔元數(shù)據(jù)

一個文檔不單單包含本身的數(shù)據(jù),也包含一些元數(shù)據(jù)--有關(guān) *文檔* 本身的信息箕戳。三個必須的元數(shù)據(jù)如下:

_index:文檔存放在哪里
_type:文檔對象的類別
_id:文檔的唯一標(biāo)識

_index

一個 索引 應(yīng)該是因共同的特性被分組到一起的文檔集合某残。 例如,你可能存儲所有的產(chǎn)品在索引 products 中陵吸,而存儲所有銷售的交易到索引 sales 中玻墅。 雖然也允許存儲不相關(guān)的數(shù)據(jù)到一個索引中,但這通匙吵妫看作是一個反模式的做法澳厢。

實(shí)際上,在 Elasticsearch 中,我們的數(shù)據(jù)是被存儲和索引在 分片 中剩拢,而一個索引僅僅是邏輯上的命名空間线得, 這個命名空間由一個或者多個分片組合在一起。

然而裸扶,這是一個內(nèi)部細(xì)節(jié)框都,我們的應(yīng)用程序根本不應(yīng)該關(guān)心分片,對于應(yīng)用程序而言呵晨,只需知道文檔位于一個 索引 內(nèi)。 Elasticsearch 會處理所有的細(xì)節(jié)熬尺。

我們將在 索引管理 介紹如何自行創(chuàng)建和管理索引摸屠,但現(xiàn)在我們將讓 Elasticsearch 幫我們創(chuàng)建索引。 所有需要我們做的就是選擇一個索引名粱哼,這個名字必須小寫季二,不能以下劃線開頭,不能包含逗號揭措。我們用 website 作為索引名舉例胯舷。

_type

數(shù)據(jù)可能在索引中只是松散的組合在一起,但是通常明確定義一些數(shù)據(jù)中的子分區(qū)是很有用的绊含。 例如桑嘶,所有的產(chǎn)品都放在一個索引中,但是你有許多不同的產(chǎn)品類別躬充,比如 "electronics" 逃顶、 "kitchen" 和 "lawn-care"。
這些文檔共享一種相同的(或非常相似)的模式:他們有一個標(biāo)題充甚、描述以政、產(chǎn)品代碼和價格。他們只是正好屬于“產(chǎn)品”下的一些子類伴找。
Elasticsearch 公開了一個稱為 types (類型)的特性盈蛮,它允許您在索引中對數(shù)據(jù)進(jìn)行邏輯分區(qū)。不同 types 的文檔可能有不同的字段技矮,但最好能夠非常相似抖誉。 我們將在 類型和映射 中更多的討論關(guān)于 types 的一些應(yīng)用和限制。

_id

ID 是一個字符串穆役, 當(dāng)它和 _index 以及 _type 組合就可以唯一確定 Elasticsearch 中的一個文檔寸五。 當(dāng)你創(chuàng)建一個新的文檔,要么提供自己的 _id 耿币,要么讓 Elasticsearch 幫你生成梳杏。

其他有待編輯

索引文檔

通過使用 index API ,文檔可以被 索引 —— 存儲和使文檔可被搜索  。 但是首先十性,我們要確定文檔的位置叛溢。正如我們剛剛討論的,一個文檔的 _index 劲适、 _type 和 _id 唯一標(biāo)識一個文檔楷掉。 我們可以提供自定義的 _id 值,或者讓 index API 自動生成霞势。
  • 如果你的文檔有一個自然的 標(biāo)識符 (例如烹植,一個 user_account 字段或其他標(biāo)識文檔的值),應(yīng)該使用這個值來做id
  • 如果你的數(shù)據(jù)沒有自然的 ID愕贡, Elasticsearch 可以幫我們自動生成 ID 草雕。

自動生成ID 的 請求的結(jié)構(gòu)調(diào)整為: 不再使用 PUT 謂詞(“使用這個 URL 存儲這個文檔”), 而是使用 POST 謂詞(“存儲文檔在這個 URL 命名空間下”)固以。

現(xiàn)在該 URL 只需包含 _index 和 _type :

如 POST /website/blog/

自動生成的 ID 是 URL-safe墩虹、 基于 Base64 編碼且長度為20個字符的 GUID 字符串。 這些 GUID 字符串由可修改的 FlakeID 模式生成憨琳,這種模式允許多個節(jié)點(diǎn)并行生成唯一 ID 诫钓,且互相之間的沖突概率幾乎為零。

取回一個文檔

為了從 Elasticsearch 中檢索出文檔 篙螟,我們?nèi)匀皇褂孟嗤?_index , _type , 和 _id 菌湃,但是 HTTP 謂詞 更改為 GET :

GET /website/blog/123

有些文檔上說的pretty參數(shù),這是用于格式化輸出的闲擦,只是為了易讀慢味,一般插件都做了這個工作。

GET 請求的響應(yīng)體包括 {"found": true} 墅冷,這證實(shí)了文檔已經(jīng)被找到纯路。 如果我們請求一個不存在的文檔,我們?nèi)耘f會得到一個 JSON 響應(yīng)體寞忿,但是 found 將會是 false 驰唬。 此外, HTTP 響應(yīng)碼將會是 404 Not Found 腔彰,而不是 200 OK 叫编。

返回文檔中的一部分

默認(rèn)情況下, GET 請求 會返回整個文檔霹抛,這個文檔正如存儲在 _source 字段中的一樣搓逾。但是也許你只對其中的 title 字段感興趣。單個字段能用  _source 參數(shù)請求得到杯拐,多個字段也能使用逗號分隔的列表來指定霞篡。

GET /website/blog/123?_source=title,text

檢測文檔是否存在

如果只想檢查一個文檔是否存在 --根本不想關(guān)心內(nèi)容--那么用  HEAD 方法來代替 GET 方法世蔗。 HEAD 請求沒有返回體,只返回一個 HTTP 請求報頭:

curl -i -XHEAD http://localhost:9200/website/blog/123

如果文檔存在朗兵, Elasticsearch 將返回一個 200 ok 的狀態(tài)碼:

HTTP/1.1 200 OK
Content-Type: text/plain; charset=UTF-8
Content-Length: 0

若文檔不存在污淋, Elasticsearch 將返回一個 404 Not Found 的狀態(tài)碼:

HTTP/1.1 404 Not Found
Content-Type: text/plain; charset=UTF-8
Content-Length: 0

更新文檔

在 Elasticsearch 中文檔是 不可改變 的,不能修改它們余掖。 相反寸爆,如果想要更新現(xiàn)有的文檔,需要 重建索引 或者進(jìn)行替換盐欺, 我們可以使用相同的 index API 進(jìn)行實(shí)現(xiàn)赁豆,在 索引文檔 中已經(jīng)進(jìn)行了討論。

PUT /website/blog/123
{
  "title": "My first blog entry",
  "text":  "I am starting to get the hang of this...",
  "date":  "2014/01/02"
}

在響應(yīng)體中找田,我們能看到 Elasticsearch 已經(jīng)增加了 _version 字段值:
如果返回體中created 標(biāo)志設(shè)置成 false 歌憨,是因?yàn)橄嗤乃饕㈩愋秃?ID 的文檔已經(jīng)存在墩衙。

在內(nèi)部,Elasticsearch 已將舊文檔標(biāo)記為已刪除甲抖,并增加一個全新的文檔漆改。 盡管你不能再對舊版本的文檔進(jìn)行訪問,但它并不會立即消失准谚。當(dāng)繼續(xù)索引更多的數(shù)據(jù)挫剑,Elasticsearch 會在后臺清理這些已刪除文檔。

在本章的后面部分柱衔,我們會介紹 update API, 這個 API 可以用于 partial updates to a document 樊破。 雖然它似乎對文檔直接進(jìn)行了修改,但實(shí)際上 Elasticsearch 按前述完全相同方式執(zhí)行以下過程:

  1. 從舊文檔中構(gòu)建json
  2. 更新該json
  3. 刪除舊文檔
  4. 索引一個新文檔

唯一的區(qū)別在于, update API 僅僅通過一個客戶端請求來實(shí)現(xiàn)這些步驟唆铐,而不需要單獨(dú)的 get 和 index 請求哲戚。

創(chuàng)建新文檔

當(dāng)我們索引一個文檔時 ,我們怎么確認(rèn)是在創(chuàng)建新的文檔艾岂,而不是覆蓋呢顺少?

index、type王浴、id可以標(biāo)識一個文檔脆炎,所以我們有兩種方式,這兩種實(shí)際上是做了一樣的事情氓辣。

PUT /website/blog/123/_create
PUT /website/blog/123?op_type=create

如果創(chuàng)建新文檔的請求成功執(zhí)行秒裕,Elasticsearch 會返回元數(shù)據(jù)和一個 201 Created 的 HTTP 響應(yīng)碼。
如果具有相同的 _index 钞啸、 _type 和 _id 的文檔已經(jīng)存在几蜻,Elasticsearch 將會返回 409 Conflict 響應(yīng)碼喇潘,以及如下的錯誤信息:

{
   "error": {
      "root_cause": [
         {
            "type": "document_already_exists_exception",
            "reason": "[blog][123]: document already exists",
            "shard": "0",
            "index": "website"
         }
      ],
      "type": "document_already_exists_exception",
      "reason": "[blog][123]: document already exists",
      "shard": "0",
      "index": "website"
   },
   "status": 409
}

刪除文檔

DELETE /website/blog/123
如果找到該文檔,Elasticsearch 將要返回一個 200 ok 的 HTTP 響應(yīng)碼入蛆,和一個類似以下結(jié)構(gòu)的響應(yīng)體响蓉。注意,字段 _version 值已經(jīng)增加:

{
  "found" :    true,
  "_index" :   "website",
  "_type" :    "blog",
  "_id" :      "123",
  "_version" : 3
}

如果文檔沒有 找到哨毁,我們將得到 404 Not Found 的響應(yīng)碼和類似這樣的響應(yīng)體:

{
  "found" :    false,
  "_index" :   "website",
  "_type" :    "blog",
  "_id" :      "123",
  "_version" : 4
}

即使文檔不存在( Found 是 false )枫甲, _version 值仍然會增加。這是 Elasticsearch 內(nèi)部記錄本的一部分扼褪,用來確保這些改變在跨多節(jié)點(diǎn)時以正確的順序執(zhí)行想幻。

正如已經(jīng)在更新整個文檔中提到的,刪除文檔不會立即將文檔從磁盤中刪除话浇,只是將文檔標(biāo)記為已刪除狀態(tài)脏毯。隨著你不斷的索引更多的數(shù)據(jù),Elasticsearch 將會在后臺清理標(biāo)記為已刪除的文檔幔崖。

處理沖突

當(dāng)我們使用 index API 更新文檔 食店,可以一次性讀取原始文檔,做我們的修改赏寇,然后重新索引 整個文檔 吉嫩。 最近的索引請求將獲勝:無論最后哪一個文檔被索引,都將被唯一存儲在 Elasticsearch 中嗅定。如果其他人同時更改這個文檔自娩,他們的更改將丟失。

有的時候系統(tǒng)是不需要控制并發(fā)的
但是往往都是需要的

根據(jù)以往數(shù)據(jù)庫并發(fā)控制經(jīng)驗(yàn)渠退,通常有兩種方式控制:

  • 悲觀并發(fā)控制
    • 這種方式被數(shù)據(jù)庫廣泛的使用忙迁,比如innodb的行鎖排它鎖
  • 樂觀并發(fā)控制
    • 比如CAS,

ElasticSearch中使用的就是樂觀鎖碎乃,就是先假定沖突不會發(fā)生姊扔,不會阻塞的先操作,然而荠锭,如果源數(shù)據(jù)在讀寫當(dāng)中被修改旱眯,更新將會失敗。應(yīng)用程序接下來將決定該如何解決沖突证九。 例如删豺,可以重試更新、使用新的數(shù)據(jù)愧怜、或者將相關(guān)情況報告給用戶呀页。

樂觀并發(fā)控制

Elasticsearch 是分布式的。當(dāng)文檔創(chuàng)建拥坛、更新或刪除時蓬蝶, 新版本的文檔必須復(fù)制到集群中的其他節(jié)點(diǎn)尘分。Elasticsearch 也是異步和并發(fā)的,這意味著這些復(fù)制請求被并行發(fā)送丸氛,并且到達(dá)目的地時也許 順序是亂的 培愁。 Elasticsearch 需要一種方法確保文檔的舊版本不會覆蓋新的版本。
當(dāng)我們之前討論 index 缓窜, GET 和 delete 請求時定续,我們指出每個文檔都有一個 _version (版本)號,當(dāng)文檔被修改時版本號遞增禾锤。 Elasticsearch 使用這個 _version 號來確保變更以正確順序得到執(zhí)行私股。如果舊版本的文檔在新版本之后到達(dá),它可以被簡單的忽略恩掷。
我們可以利用 _version 號來確保 應(yīng)用中相互沖突的變更不會導(dǎo)致數(shù)據(jù)丟失倡鲸。我們通過指定想要修改文檔的 version 號來達(dá)到這個目的。 如果該版本不是當(dāng)前版本號黄娘,我們的請求將會失敗峭状。

// 先創(chuàng)建一個新的文檔
PUT /website/blog/1/_create
{
  "title": "My first blog entry",
  "text":  "Just trying this out..."
}

//然后檢索看到version是1
GET /website/blog/1
                {
                  "_index" :   "website",
                  "_type" :    "blog",
                  "_id" :      "1",
                  "_version" : 1,
                  "found" :    true,
                  "_source" :  {
                      "title": "My first blog entry",
                      "text":  "Just trying this out..."
                  }
                }
                
                
//現(xiàn)在,當(dāng)我們嘗試通過重建文檔的索引來保存修改逼争,我們指定 version 為我們的修改會被應(yīng)用的版本:
PUT /website/blog/1?version=1
{
  "title": "My first blog entry",
  "text":  "Starting to get the hang of this..."
}

上述是內(nèi)部機(jī)制控制版本號
我們可以把版本號通過外部系統(tǒng)控制

外部版本號的處理方式和我們之前討論的內(nèi)部版本號的處理方式有些不同宁炫, Elasticsearch 不是檢查當(dāng)前 _version 和請求中指定的版本號是否相同, 而是檢查當(dāng)前 _version 是否 小于 指定的版本號氮凝。 如果請求成功,外部的版本號作為文檔的新 _version 進(jìn)行存儲望忆。

PUT /website/blog/2?version=5&version_type=external
{
  "title": "My first external blog entry",
  "text":  "Starting to get the hang of this..."
}

注意罩阵,這里的version只能大,不能比ela中的小

文檔的部分更新

在 更新整個文檔 , 我們已經(jīng)介紹過 更新一個文檔的方法是檢索并修改它启摄,然后重新索引整個文檔稿壁,這的確如此。
然而歉备,使用 update API 我們還可以部分更新文檔傅是,例如在某個請求時對計數(shù)器進(jìn)行累加。
我們也介紹過文檔是不可變的:他們不能被修改蕾羊,只能被替換喧笔。
update API 必須遵循同樣的規(guī)則。 從外部來看龟再,我們在一個文檔的某個位置進(jìn)行部分更新书闸。
然而在內(nèi)部, update API 簡單使用與之前描述相同的 檢索-修改-重建索引 的處理過程利凑。
區(qū)別在于這個過程發(fā)生在分片內(nèi)部浆劲,這樣就避免了多次請求的網(wǎng)絡(luò)開銷嫌术。
通過減少檢索和重建索引步驟之間的時間,我們也減少了其他進(jìn)程的變更帶來沖突的可能性牌借。
update 請求最簡單的一種形式是接收文檔的一部分作為 doc 的參數(shù)度气, 它只是與現(xiàn)有的文檔進(jìn)行合并。
對象被合并到一起膨报,覆蓋現(xiàn)有的字段磷籍,增加新的字段。 例如丙躏,我們增加字段 tags 和 views 到我們的博客文章择示,如下所示:

POST /website/blog/1/_update
{
   "doc" : {
      "tags" : [ "testing" ],
      "views": 0
   }
}

使用腳本更新

這個暫不看了

更新的文檔可能不存在

假設(shè)我們需要 在 Elasticsearch 中存儲一個頁面訪問量計數(shù)器。 每當(dāng)有用戶瀏覽網(wǎng)頁晒旅,我們對該頁面的計數(shù)器進(jìn)行累加栅盲。但是,如果它是一個新網(wǎng)頁废恋,我們不能確定計數(shù)器已經(jīng)存在谈秫。 如果我們嘗試更新一個不存在的文檔,那么更新操作將會失敗鱼鼓。在這樣的情況下拟烫,我們可以使用 upsert 參數(shù),指定如果文檔不存在就應(yīng)該先創(chuàng)建它:

POST /website/pageviews/1/_update
{
   "script" : "ctx._source.views+=1",
   "upsert": {
       "views": 1
   }
}
//第一次運(yùn)行這個請求時迄本, upsert 值作為新文檔被索引硕淑,初始化 views 字段為 1 。 在后續(xù)的運(yùn)行中嘉赎,由于文檔已經(jīng)存在置媳, script 更新操作將替代 upsert 進(jìn)行應(yīng)用,對 views 計數(shù)器進(jìn)行累加公条。

沖突

如果沖突了拇囊,我們還想重試,比如計數(shù)器這個完全可以直接重試的操作
我們可以

POST /website/pageviews/1/_update?retry_on_conflict=5
{
   "script" : "ctx._source.views+=1",
   "upsert": {
       "views": 0
   }
}
//這里的5表示重試5次靶橱。

在增量操作無關(guān)順序的場景寥袭,例如遞增計數(shù)器等這個方法十分有效,但是在其他情況下變更的順序 是 非常重要的关霸。 類似 index API 传黄, update API 默認(rèn)采用 最終寫入生效 的方案,但它也接受一個 version 參數(shù)來允許你使用 optimistic concurrency control 指定想要更新文檔的版本谒拴。

取回多個文檔

Elasticsearch 的速度已經(jīng)很快了尝江,但甚至能更快。 將多個請求合并成一個英上,避免單獨(dú)處理每個請求花費(fèi)的網(wǎng)絡(luò)延時和開銷炭序。
如果你需要從 Elasticsearch 檢索很多文檔啤覆,那么使用 multi-get 或者 mget API 來將這些檢索請求放在一個請求中,將比逐個文檔請求更快地檢索到全部文檔惭聂。
mget API 要求有一個 docs 數(shù)組作為參數(shù)窗声,每個 元素包含需要檢索文檔的元數(shù)據(jù), 包括 _index 辜纲、 _type 和 _id 笨觅。
如果你想檢索一個或者多個特定的字段,那么你可以通過 _source 參數(shù)來指定這些字段的名字:
示例:

GET /_mget
{
   "docs" : [
      {
         "_index" : "website",
         "_type" :  "blog",
         "_id" :    2
      },
      {
         "_index" : "website",
         "_type" :  "pageviews",
         "_id" :    1,
         "_source": "views"
      }
   ]
}

該響應(yīng)體也包含一個 docs 數(shù)組 耕腾, 對于每一個在請求中指定的文檔见剩,這個數(shù)組中都包含有一個對應(yīng)的響應(yīng),且順序與請求中的順序相同扫俺。 其中的每一個響應(yīng)都和使用單個 get request 請求所得到的響應(yīng)體相同:

{
   "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
         }
      }
   ]
}

如果想檢索的數(shù)據(jù)都在相同的 _index 中(甚至相同的 _type 中)苍苞,則可以在 URL 中指定默認(rèn)的 /_index 或者默認(rèn)的 /_index/_type 。
你仍然可以通過單獨(dú)請求覆蓋這些值:

GET /website/blog/_mget
{
   "docs" : [
      { "_id" : 2 },
      { "_type" : "pageviews", "_id" :   1 }
   ]
}

事實(shí)上狼纬,如果所有文檔的 _index 和 _type 都是相同的羹呵,你可以只傳一個 ids 數(shù)組,而不是整個 docs 數(shù)組:

GET /website/blog/_mget
{
   "ids" : [ "2", "1" ]
}

注意疗琉,我們請求的第二個文檔是不存在的冈欢。我們指定類型為 blog ,但是文檔 ID 1 的類型是 pageviews 盈简,這個不存在的情況將在響應(yīng)體中被報告:

{
  "docs" : [
    {
      "_index" :   "website",
      "_type" :    "blog",
      "_id" :      "2",
      "......
    },
    {
      "_index" :   "website",
      "_type" :    "blog",
      "_id" :      "1",
      "found":  false
   }
  ]
}

事實(shí)上第二個文檔未能找到并不妨礙第一個文檔被檢索到凑耻。每個文檔都是單獨(dú)檢索和報告的。

實(shí)際上就算都沒有找到柠贤,請求Http碼依舊是200拳话,因?yàn)檫@個主體是megt請求。

代價較小的批量操作

與 mget 可以使我們一次取回多個文檔同樣的方式种吸, bulk API 允許在單個步驟中進(jìn)行多次 create 、 index 呀非、 update 或 delete 請求坚俗。
如果你需要索引一個數(shù)據(jù)流比如日志事件,它可以排隊和索引數(shù)百或數(shù)千批次岸裙。bulk 與其他的請求體格式稍有不同猖败,如下所示:

{ action: { metadata }}\n
{ request body        }\n
{ action: { metadata }}\n
{ request body        }\n
...

這種格式類似一個有效的單行 JSON 文檔 流 ,它通過換行符(\n)連接到一起降允。注意兩個要點(diǎn):

  • 每行一定以換行符結(jié)束恩闻,包括最后一行,這就是一行結(jié)束的標(biāo)記
  • 這些行不能包含未轉(zhuǎn)義的換行符剧董,因?yàn)樗麄儗馕鲈斐筛蓴_幢尚。這意味著這個 JSON 不 能使用 pretty 參數(shù)打印破停。

action/metadata 行指定 哪一個文檔 做 什么操作 。
action 必須是以下選項(xiàng)之一:

  • create
    • 如果文檔不存在尉剩,那么就創(chuàng)建它真慢。詳情請見 創(chuàng)建新文檔
  • index
    • 創(chuàng)建一個新文檔或者替換一個現(xiàn)有的文檔理茎。詳情請見 索引文檔更新整個文檔黑界。
  • update
    • 部分更新一個文檔。詳情請見 文檔的部分更新皂林。
  • delete
    • 刪除一個文檔朗鸠。詳情請見 刪除文檔

metadata 應(yīng)該 指定被索引础倍、創(chuàng)建烛占、更新或者刪除的文檔的 _index 、 _type 和 _id 著隆。
例如扰楼,一個 delete 請求看起來是這樣的:

{ "delete": { "_index": "website", "_type": "blog", "_id": "123" }}
  • request body 行由文檔的 _source 本身組成--文檔包含的字段和值。
  • 它是 index 和 create 操作所必需的美浦,這是有道理的:你必須提供文檔以索引弦赖。
  • 它也是 update 操作所必需的,并且應(yīng)該包含你傳遞給 update API 的相同請求體: doc 浦辨、 upsert 蹬竖、 script 等等。
  • 刪除操作不需要 request body 行流酬。
    示例:
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"} }
  • 注意delete動作下沒有請求體币厕,他后面跟著另一個操作
  • 最后一個換行符不要忘了。

這個 Elasticsearch 響應(yīng)包含 items 數(shù)組芽腾, 這個數(shù)組的內(nèi)容是以請求的順序列出來的每個請求的結(jié)果旦装。

{
    "took": 4,
    "errors":   flase,
    "items": [
      {  "delete": {
            "_index":   "website",
            "_type":    "blog",
            "_id":      "123",
            "_version": 2,
            "status":   200,
            "found":    true
      }},
      .....
     ]
 }

每個子請求都是獨(dú)立執(zhí)行,因此某個子請求的失敗不會對其他子請求的成功與否造成影響摊滔。 如果其中任何子請求失敗阴绢,最頂層的 error 標(biāo)志被設(shè)置為 true ,并且在相應(yīng)的請求報告出錯誤明細(xì):

  • bulk 請求不是原子的: 不能用它來實(shí)現(xiàn)事務(wù)控制艰躺。
  • 每個請求是單獨(dú)處理的呻袭,因此一個請求的成功或失敗不會影響其他的請求。

不要重復(fù)制定INdex和Type

也許你正在批量索引日志數(shù)據(jù)到相同的 index 和 type 中腺兴。
但為每一個文檔指定相同的元數(shù)據(jù)是一種浪費(fèi)左电。
相反,可以像 mget API 一樣,在 bulk 請求的 URL 中接收默認(rèn)的 /_index 或者 /_index/_type :

POST /website/_bulk
{ "index": { "_type": "log" }}
{ "event": "User logged in" }

你仍然可以覆蓋元數(shù)據(jù)行中的 _index 和 _type , 但是它將使用 URL 中的這些元數(shù)據(jù)值作為默認(rèn)值:

POST /website/log/_bulk
{ "index": {}}
{ "event": "User logged in" }
{ "index": { "_type": "blog" }}
{ "title": "Overriding the default type" }

大小控制

整個批量請求都需要由接收到請求的節(jié)點(diǎn)加載到內(nèi)存中篓足,因此該請求越大段誊,其他請求所能獲得的內(nèi)存就越少。 批量請求的大小有一個最佳值纷纫,大于這個值枕扫,性能將不再提升,甚至?xí)陆怠?br> 但是最佳值不是一個固定的值辱魁。
它完全取決于硬件烟瞧、文檔的大小和復(fù)雜度、索引和搜索的負(fù)載的整體情況染簇。
幸運(yùn)的是参滴,很容易找到這個 最佳點(diǎn) :
通過批量索引典型文檔,并不斷增加批量大小進(jìn)行嘗試锻弓。
當(dāng)性能開始下降砾赔,那么你的批量大小就太大了。

一個好的辦法是開始時將 1,000 到 5,000 個文檔作為一個批次, 如果你的文檔非常大青灼,那么就減少批量的文檔個數(shù)暴心。
一個好的批量大小在開始處理后所占用的物理大小約為 5-15 MB。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末杂拨,一起剝皮案震驚了整個濱河市专普,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌弹沽,老刑警劉巖檀夹,帶你破解...
    沈念sama閱讀 216,997評論 6 502
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異策橘,居然都是意外死亡炸渡,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,603評論 3 392
  • 文/潘曉璐 我一進(jìn)店門丽已,熙熙樓的掌柜王于貴愁眉苦臉地迎上來蚌堵,“玉大人,你說我怎么就攤上這事沛婴〕秸” “怎么了?”我有些...
    開封第一講書人閱讀 163,359評論 0 353
  • 文/不壞的土叔 我叫張陵瘸味,是天一觀的道長。 經(jīng)常有香客問我够挂,道長旁仿,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,309評論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮枯冈,結(jié)果婚禮上毅贮,老公的妹妹穿的比我還像新娘。我一直安慰自己尘奏,他們只是感情好滩褥,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,346評論 6 390
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著炫加,像睡著了一般瑰煎。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上俗孝,一...
    開封第一講書人閱讀 51,258評論 1 300
  • 那天酒甸,我揣著相機(jī)與錄音,去河邊找鬼赋铝。 笑死插勤,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的革骨。 我是一名探鬼主播农尖,決...
    沈念sama閱讀 40,122評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼良哲!你這毒婦竟也來了盛卡?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,970評論 0 275
  • 序言:老撾萬榮一對情侶失蹤臂外,失蹤者是張志新(化名)和其女友劉穎窟扑,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體漏健,經(jīng)...
    沈念sama閱讀 45,403評論 1 313
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡嚎货,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,596評論 3 334
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了蔫浆。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片殖属。...
    茶點(diǎn)故事閱讀 39,769評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖瓦盛,靈堂內(nèi)的尸體忽然破棺而出洗显,到底是詐尸還是另有隱情,我是刑警寧澤原环,帶...
    沈念sama閱讀 35,464評論 5 344
  • 正文 年R本政府宣布挠唆,位于F島的核電站,受9級特大地震影響嘱吗,放射性物質(zhì)發(fā)生泄漏玄组。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,075評論 3 327
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望俄讹。 院中可真熱鬧哆致,春花似錦、人聲如沸患膛。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,705評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽踪蹬。三九已至胞此,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間延曙,已是汗流浹背豌鹤。 一陣腳步聲響...
    開封第一講書人閱讀 32,848評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留枝缔,地道東北人布疙。 一個月前我還...
    沈念sama閱讀 47,831評論 2 370
  • 正文 我出身青樓,卻偏偏與公主長得像愿卸,于是被迫代替她去往敵國和親灵临。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,678評論 2 354