Elasticsearch學習筆記(九)partial update


一、什么是partial update?


PUT /index/type/id,創建文檔&替換文檔,就是一樣的語法

一般對應到應用程序中,每次的執行流程基本是這樣的:

(1)應用程序先發起一個get請求,獲取到document,展示到前台界面,供用戶查看和修改
(2)用戶在前台界面修改數據,發送到后台
(3)后台代碼,會將用戶修改的數據在內存中進行執行,然后封裝好修改后的全量數據
(4)然后發送PUT請求,到es中,進行全量替換
(5)es將老的document標記為deleted,然后重新創建一個新的document

partial update

POST /index/type/id/_update
{
   "doc": {
      "要修改的少數幾個field即可,不需要全量的數據"
   }
}

PUT /test_index/test_type/10
{
  "test_field1": "test1",
  "test_field2": "test2"
}

POST /test_index/test_type/10/_update
{
  "doc": {
    "test_field2": "updated test2"
  }
}

看起來,好像就比較方便了,每次就傳遞少數幾個發生修改的field即可,不需要將全量的document數據發送過去

二、partial update實現原理以及其優點


          partial update直接將數據更新到document中就完成了修改,不用事先先發起一個GET請求數據進行修改然后在將修改后的數據發回去。
          es內部:partial update的執行和全量替換一致。
                        (1)內部先get獲取document
                        (2)將更新的field更新到document的json中
                        (3)將老的document標記為deleted
                        (4)創建新的document
          優點:
                (1)所有查詢,修改和寫回操作均發生在同一個shard內,避免了不必要的網絡數據傳輸帶來的開銷,大大提升了性能(減少了兩次請求,一次GET請求,一次回寫請求)
                (2)減少修改和查詢中的時間間隔,有效減少並發沖突的情況
                (3)內置樂觀鎖並發控制

                         POST /test_index/test_type/id/_update?retry_on_conflict=2
{
  "doc": {
    "num":32
  }
}
如果更新失敗,則獲取最新的版本號再次進行更新,最多重試retry_on_conflict指定的次數
                        POST /test_index/test_type/11/_update?version=3
{
  "doc": {
    "num":32
  }
}

三、基於groovy腳本的partial update


        1、內置腳本

             示例:
                        PUT /test_index/test_type/11
{
  "num":0,
  "tags":[]
}
              更新num字段:
                POST /test_index/test_type/11/_update
{
  "script": "ctx._source.num+=8"
}

      2、外部腳本


                    在Elasticsearch的安裝目錄下的 \config\scripts內添加指定的groovy腳本

                (1)添加腳本 test_update_num.groovy

                     腳本 代碼:
                               ctx._source.num+=1
                      執行腳本:
                        POST /test_index/test_type/11/_update
{
  "script": {
    "lang": "groovy",
    "file": "test_update_num"
  }
}


                2)添加腳本:test-add-tags.groovy

                     腳本代碼:ctx._source.tags+=new_tag
                     執行腳本:
                                    POST /test_index/test_type/11/_update
{
  "script": {
    "lang": "groovy",
    "file": "test-add-tags",
    "params": {
      "new_tag":"tag_value"
    }
  }
}

                3)添加腳本:test-delete-document.groovy

                     腳本代碼:
                                ctx.op=ctx._source.num==count?"delete":'none'
                     執行腳本:
POST /test_index/test_type/11/_update
{
  "script": {
    "lang": "groovy",
    "file": "test-delete-document",
    "params": {
      "count":17
    }
  }
}

                    (4)upsert操作


                        如果指定的document不存在,就執行upsert中的初始化操作;如果指定的document存在,就執行doc或者script指定的partial update操作

POST /test_index/test_type/11/_update
{
   "script" : "ctx._source.num+=1",
   "upsert": {
       "num": 0,
       "tags": []
   }

}
   






免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM