1. 程式人生 > >elasticsearch更新文件資料

elasticsearch更新文件資料

文字方式批量更新多欄位

使用更新請求最簡單的一種用途就是新增新資料。新的資料會被合併到現有資料中,而如果存在相同的欄位,就會被新的資料所替換。例如我們可以為我們的部落格新增tagsviews欄位:

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

如果請求成功,我們就會收到一個類似於索引時返回的內容

使用指令碼進行更新

預設的指令碼語言叫做MVEL,但是Elasticsearch也支援JavaScript, Groovy 以及 Python。MVEL是一個簡單高效的JAVA基礎動態指令碼語言,它的語法類似於Javascript。

指令碼語言可以在更新

API中被用來修改_source中的內容,而它在指令碼中被稱為ctx._source。例如,我們可以使用指令碼來增加博文中views的數字:

POST /website/blog/1/_update
{
   "script" : "ctx._source.views+=1"
}

我們同樣可以使用指令碼在tags陣列中新增新的tag。在這個例子中,我們把新的tag宣告為一個變數,而不是將他寫死在指令碼中。這樣Elasticsearch就可以重新使用這個指令碼進行tag的新增,而不用再次重新編寫指令碼了:

POST /website/blog/1/_update
{
   "script" : "ctx._source.tags+=new_tag"
, "params" : { "new_tag" : "search" } }

獲取文件,後兩項發生了變化:

{
   "_index":    "website",
   "_type":     "blog",
   "_id":       "1",
   "_version":  5,
   "found":     true,
   "_source": {
      "title":  "My first blog entry",
      "text":   "Starting to get the hang of this...",
      "tags"
: ["testing", "search"], <1> "views": 1 <2> } }
  1. tags陣列中出現了search
  2. views欄位增加了。

我們甚至可以使用ctx.op來根據內容選擇是否刪除一個文件:

POST /website/blog/1/_update
{
   "script" : "ctx.op = ctx._source.views == count ? 'delete' : 'none'",
    "params" : {
        "count": 1
    }
}

更新一篇可能不存在的文件

想象一下,我們可能需要在Elasticsearch中儲存一個頁面計數器。每次使用者訪問這個頁面,我們就增加一下當前頁面的計數器。但是如果這是個新的頁面,我們不能確保這個計數器已經存在。如果我們試著去更新一個不存在的文件,更新操作就會失敗。

為了防止上述情況的發生,我們可以使用upsert引數來設定文件不存在時,它應該被建立:

POST /website/pageviews/1/_update
{
   "script" : "ctx._source.views+=1",
  "upsert": {
       "views": 1
   }
}

首次執行這個請求時,upsert的內容會被索引成新的文件,它將views欄位初始化為1。當之後再請求時,文件已經存在,所以指令碼更新就會被執行,views計數器就會增加。

為了避免丟失資料,更新API會在獲取步驟中獲取當前文件中的_version,然後將其傳遞給重新索引步驟中的索引請求。如果其他的程序在這兩部之間修改了這個文件,那麼_version就會不同,這樣更新就會失敗。

對於很多的區域性更新來說,文件有沒有發生變化實際上是不重要的。例如,兩個程序都要增加頁面瀏覽的計數器,誰先誰後其實並不重要 —— 發生衝突時只需要重新來過即可。

你可以通過設定retry_on_conflict引數來設定自動完成這項請求的次數,它的預設值是0

POST /website/pageviews/1/_update?retry_on_conflict=5 <1>
{
   "script" : "ctx._source.views+=1",
   "upsert": {
       "views": 0
   }
}
  1. 失敗前重新嘗試5次
這個引數非常適用於類似於增加計數器這種無關順序的請求