elasticsearch6.7 05. Document APIs(7)Update By Query API

来源:https://www.cnblogs.com/wtc1994/archive/2019/04/14/10707198.html
-Advertisement-
Play Games

6、Update By Query API 介面可以在不改變 source 的情況下對 index 中的每個文檔進行更新。這對於獲取新屬性或其他聯機映射更改很有用。以下是 API: 這將返回如下內容: _update_by_query 在開始執行的時候獲得一個快照,並使用內部版本控制對找到的內容進行 ...


6、Update By Query API

_update_by_query 介面可以在不改變 source 的情況下對 index 中的每個文檔進行更新。這對於獲取新屬性或其他聯機映射更改很有用。以下是 API:

POST twitter/_update_by_query?conflicts=proceed

這將返回如下內容:

{
  "took" : 147,
  "timed_out": false,
  "updated": 120,
  "deleted": 0,
  "batches": 1,
  "version_conflicts": 0,
  "noops": 0,
  "retries": {
    "bulk": 0,
    "search": 0
  },
  "throttled_millis": 0,
  "requests_per_second": -1.0,
  "throttled_until_millis": 0,
  "total": 120,
  "failures" : [ ]
}

_update_by_query 在開始執行的時候獲得一個快照,並使用內部版本控制對找到的內容進行索引。這意味著,如果文檔在獲取快照和處理索引請求之間發生更改,則會出現版本衝突。當版本匹配時,文檔會更新,對應的版本號也會遞增。

由於內部版本控制不支持將0作為有效版本號,因此無法使用_update_by_query更新版本號為零的文檔。

所有的更新和查詢失敗都將導致_update_by_query 中止,並且在 響應中返回 failures。已經更新的內容仍然存在。也就是說這個操作不會回滾,只會中止。當第一個錯誤引起中止後,所有的錯誤都會返回到 failures 元素中,因此有可能有相當多的失敗實例。

如何您想在遇到版本衝突時繼續執行 _updata_by_query,那麼可以在 url 中設置 conflicts=proceed 或是在請求中設置 conflicts":"proceed。第一個例子是這樣設置的,因為它想要獲得發生改變的線上映射,版本衝突僅僅意味著衝突文檔在update_by_query 的開始時間和試圖更新文檔的時間之間被更新。這沒關係,因為該更新將獲取聯機映射更新。

下麵的例子將會 update twitter 索引中的 tweets:

POST twitter/_doc/_update_by_query?conflicts=proceed

您還可以使用 Query DSL 限制 _update_by_query,下麵的例子將會更新 twitter 索引中所有 user 欄位為 kimchy 的文檔:

POST twitter/_update_by_query?conflicts=proceed
{
  "query": { 
    "term": {
      "user": "kimchy"
    }
  }
}

目前,我們在更新文檔的時候沒有更改 source。這對諸如獲取新屬性很有用,但只是其中一般的樂趣。_update_by_query 支持用腳本來更新文檔。下麵的例子將會把所有user為 kimchy 的 likes 欄位加 1:

POST twitter/_update_by_query
{
  "script": {
    "source": "ctx._source.likes++",
    "lang": "painless"
  },
  "query": {
    "term": {
      "user": "kimchy"
    }
  }
}

正如在 update API 中一樣,您可以設置 ctx.op 來更改執行的操作:

  • noop:如果腳本確定不需要進行任何更改,請設置 ctx.op=noop。這將導致_update_by_query 從其更新中忽略該文檔。此無操作將在響應體的 noop 計數器中報告。
  • delete:如果你決定刪除該文檔,請設置 ctx.op=delete。刪除操作會在響應體的 deleted 計數器中報告。

將 ctx.op 設置為其他值都是錯誤的,在 ctx 中設置其他欄位也都是錯誤的。

請註意,如果我們取消設置 conflicts=proceed。在這種情況下,我們希望版本衝突能夠中止該操作以便於我們處理失敗的原因。

此API不允許您移動涉及到的文檔,只能修改它的 source。這是有意為之的。因為我們不想將文件移動位置。

此API也可以一次修改多個索引和多個類型,如:

POST twitter,blog/_doc,post/_update_by_query

如何設置了routing ,那麼操作的分片還應該滿足路由的條件,如:

POST twitter/_update_by_query?routing=1

_update_by_query 預設使用的scroll 批次大小是 1000,您可以通過設置 scroll_size來 修改此值:

POST twitter/_update_by_query?scroll_size=100

_update_by_query 也可以指定 Ingest Node介面的 pipeline,如:

PUT _ingest/pipeline/set-foo
{
  "description" : "sets foo",
  "processors" : [ {
      "set" : {
        "field": "foo",
        "value": "bar"
      }
  } ]
}
POST twitter/_update_by_query?pipeline=set-foo

6.1 URL 參數(URL Parameters)

_update_by_query 介面支持的參數有 prettyrefreshwait_for_completionwait_for_active_shardstimeoutscroll

  • refresh
    • 執行完更新操作後刷新update_by_query 中查詢涉及的分片。這和 update API 的 refresh 不同,update API 的 refresh 僅刷新接收到更新請求的分片。_update_by_query 的 refresh 參數不支持 wait_for。
  • wait_for_completion
    • 如果請求中 wait_for_completion=false,那麼 elasticsearch 將會執行預檢查、執行請求,然後返回可與任務 API 一起使用的任務,以取消或獲取任務的狀態。elasticsearch 還將在.task/task/${taskId} 處創建此任務的記錄文檔。您可以根據需要保留或刪除該文檔。用完刪除後,elasticsearch 可以回收其占用的空間。
  • wait_for_active_shards
    • 控制在執行請求前需要有幾個可用的分片數。
  • timeout
    • 控制每個請求等待分片從不可用狀態到可用狀態的時間。因為_update_by_query 使用滾動搜索,所以可以指定 scroll 參數來控制它使 “搜索上下文” 保持活動的時間,例如:scroll=10m。預設情況下,它是 5 分鐘。
  • request_per_second
    • 可以設置為任意正數(如 1.4、6、1000 等)。通過設置等待的時間來控制_update_by_query 批量執行更新操作的速率。當 requests_per_second 設置為 - 1 時禁用該控制。

速率限制是通過在批量處理之間等待來完成的,這樣就可以為_update_by_query內部使用的回滾指定一個考慮填充的超時時間。填充時間是批處理大小除以 requests_per_second 與寫入時間只差。預設情況下,批處理大小為 1000,因此如 request_per_second 設置為 500:

target_time = 1000 / 500 per second = 2 seconds
wait_time = target_time - write_time = 2 seconds - .5 seconds = 1.5 seconds

由於該批處理是作為單個 _bulk 請求發出的,因此大批量的請求將導致ElasticSearch創建多個請求,然後在啟動下一個集合之前等待一段時間。這是“突發”而不是“平穩”。預設值為-1。

6.2 響應體(Response body)

{
  "took" : 147,
  "timed_out": false,
  "total": 5,
  "updated": 5,
  "deleted": 0,
  "batches": 1,
  "version_conflicts": 0,
  "noops": 0,
  "retries": {
    "bulk": 0,
    "search": 0
  },
  "throttled_millis": 0,
  "requests_per_second": -1.0,
  "throttled_until_millis": 0,
  "failures" : [ ]
}
  • took
    • 整個操作耗費的毫秒數
  • timed_out
    • 如果在執行 _update_by_query 操作時出現超時,那麼這個標識將會返回 true
  • total
    • 成功執行操作的文檔的數量
  • updated
    • 成功的更新了多少個文檔
  • deleted
    • 成功的刪除了多少個文檔
  • batches
    • 回滾數
  • verison_conflicts
    • 操作過程中出現版本衝突的數量
  • noops
    • 由於 ctx.op=noop 設置造成的忽略的文檔數
  • retries
    • 重覆嘗試的次數,bulk 是批量更新操作重覆嘗試的次數,search 是查詢的重覆嘗試次數
  • throthled_millis
    • requests_per_second 參數引起的請求等待時間
  • requests_per_second
    • 在操作過程中,每秒執行的請求數
  • throttled_until_millis
    • 執行_update_by_query時這個值始終0,只在在調用Task API時該值才有意義,它表示下一次(自紀元以來)為了符合requests_per_second將再次執行請求的毫秒數。
  • failures
    • 執行失敗的數組,包含在執行過程中任何不可恢復的錯誤。如果這個數組不是空的,那麼請求會因為這些失敗而中止。_delete_by_query是使用批處理實現的,任何失敗都會導致整個執行被中止。可以使用conflicts參數來防止reindex在版本衝突時造成操作中止。

6.3 結合 taskAPi 使用(Works with the Task API)

您可以使用 Task API 獲取任何正在進行 update_by_query 請求的狀態:

GET _tasks?detailed=true&actions=*byquery

返回值:

{
  "nodes" : {
    "r1A2WoRbTwKZ516z6NEs5A" : {
      "name" : "r1A2WoR",
      "transport_address" : "127.0.0.1:9300",
      "host" : "127.0.0.1",
      "ip" : "127.0.0.1:9300",
      "attributes" : {
        "testattr" : "test",
        "portsfile" : "true"
      },
      "tasks" : {
        "r1A2WoRbTwKZ516z6NEs5A:36619" : {
          "node" : "r1A2WoRbTwKZ516z6NEs5A",
          "id" : 36619,
          "type" : "transport",
          "action" : "indices:data/write/update/byquery",
          "status" : {    
            "total" : 6154,
            "updated" : 3500,
            "created" : 0,
            "deleted" : 0,
            "batches" : 4,
            "version_conflicts" : 0,
            "noops" : 0,
            "retries": {
              "bulk": 0,
              "search": 0
            },
            "throttled_millis": 0
          },
          "description" : ""
        }
      }
    }
  }
}

status:這個對象包含了當前任務的實際狀態。total 欄位是本次操作需要重新索引的文檔數。你可以通過 updated, created, and deleted 欄位估計處理進度。當以上幾個欄位的和等於 total 欄位時,請求就執行完畢了。

你可以使用 task id 查看某個任務。下例查看task id為 r1A2WoRbTwKZ516z6NEs5A:36619的任務信息:

GET /_tasks/r1A2WoRbTwKZ516z6NEs5A:36619

該 API 可以與wait_for_comletion=false集成使用,可以清晰的查看已完成任務的狀態。如果任務已經完成,並且在其上設置了wait_for_completion=false,那麼請求將會返回結果或是錯誤欄位。此功能的代價是當wait_for_completion=false時會在.tasks/task/${taskId}目錄下會創建文檔。您可以根據需要刪除該文檔。

6.4 取消任務(Works with the Cancel Task API)

任何_update_by_query操作都可以通過task cancel API來取消,如:

POST _tasks/r1A2WoRbTwKZ516z6NEs5A:36619/_cancel

取消應該執行很快,但可能需要幾秒鐘。在此期間上面的 task status API將繼續列出該任務,直到它完全被取消了。

6.5 閾值(Rethrottling)

在正在執行的請求中,requests_per_second的值可以在運行時通過_rethrotted API進行修改:

POST _update_by_query/r1A2WoRbTwKZ516z6NEs5A:36619/_rethrottle?requests_per_second=-1

可以使用tasks API找到任務ID。

和 requests_per_seconds 參數設置一樣,rethrottling 參數可以是 - 1 (禁用限制)或是其他十進位數(如 1.7 或 12 )。rethrottling 參數能提高查詢速度且會立即生效,但是降低速度必須等到當前操作執行完後才起作用。這可以防止滾動超時

6.6 切片 (slicing)

update_by_query支持 sliced scroll 來使更新操作並行進行。這能提高效率並且提供了一種將請求分解為較小的部分的便捷方式。

6.6.1 手動切片 (Manually slicing)

通過為每個請求提供切片 ID 和切片總數,手動將 update_by_query操作進行分解:

POST twitter/_update_by_query
{
  "slice": {
    "id": 0,
    "max": 2
  },
  "script": {
    "source": "ctx._source['extra'] = 'test'"
  }
}
POST twitter/_update_by_query
{
  "slice": {
    "id": 1,
    "max": 2
  },
  "script": {
    "source": "ctx._source['extra'] = 'test'"
  }
}

你可以這樣驗證上述 api 的結果:

GET _refresh
POST twitter/_search?size=0&q=extra:test&filter_path=hits.total

返回如下的的結果:

{
  "hits": {
    "total": 120
  }
}

6.6.2 自動切片 (Automatic slicing)

也可以讓 update_by_query 自動並行地滾動切片。使用 slices 指定要使用的切片數:

POST twitter/_update_by_query?refresh&slices=5
{
  "script": {
    "source": "ctx._source['extra'] = 'test'"
  }
}

您可以通過下列語句驗證運行結果:

POST twitter/_search?size=0&q=extra:test&filter_path=hits.total

返回如下的的結果:

{
  "hits": {
    "total": 120
  }
}

slices 設置為 auto 將允許 ElasticSearch 選擇要使用的切片數。此設置將使用一個分片一個切片,直至達到某個限制。如果存在多個源索引,它將根據具有最少分片的那個索引所擁有的分片數來作為切片數。

向_delete_by_query 添加 slices 只會自動執行上一節中使用的手動過程,這意味著它有一些怪癖:

  • 您可以在 Tasks API 中查看這些請求。這些子請求是具有 slices 請求的任務的 “子 " 任務。
  • 僅使用 slices 獲取請求的任務狀態 (包含已完成切片的狀態)。
  • 這些子請求可單獨定址,例如取消和重新限制。
  • 使用 slices 重新處理請求將按比例重新調整未完成的子請求。
  • 使用 slices 取消請求將取消每個子請求。
  • 由於 slices 的性質,每個子請求都不會獲得完全均勻的文檔部分。這些切片文檔都會被處理,但某些切片可能比其他切片分到更大的文檔。
  • requests_per_second 這樣的參數和帶有 sizeslices 請求 (按指定比例分配給每個子請求)。將其與上述關於分佈不均勻的點相結合,您應該得出結論,使用 slicessize 可能不會刪除指定大小的文檔。
  • 每個子請求都會獲得和源索引略有不同的快照,儘管這些快照幾乎同時進行。

6.6.3 選擇 slices 的數量

如果 slices 設置為 auto,elasticsearch 將會自動為大多數索引選擇一個合理的數量。如果您設置手動切片或以其他方式來調整自動切片,請遵循以下準則:

當切片的數量等於索引的分片數時,查詢性能最好。如果這個數量太大(如 500), 請選擇一個較小的數字,因為太多的切片會影響性能。設置高於分片數的切片通常不會提高效率反而會增加開銷。

update 的性能與可用的切片數量呈正相關。

查詢或更新是否是影響此時運行時性能的主要原因,這取決於reindexed時的文檔和集群的資源。

6.7 獲取新屬性(pick up a new property)

假設您創建了一個沒有動態映射的索引,然後向裡面添加了數據,現在添加後一個 mapping value 可以從數據中獲取更多的欄位,如:

PUT test
{
  "mappings": {
    "_doc": {
      "dynamic": false,   【1】
      "properties": {
        "text": {"type": "text"}
      }
    }
  }
}

POST test/_doc?refresh
{
  "text": "words words",
  "flag": "bar"
}
POST test/_doc?refresh
{
  "text": "words words",
  "flag": "foo"
}
PUT test/_mapping/_doc   【2】
{
  "properties": {
    "text": {"type": "text"},
    "flag": {"type": "text", "analyzer": "keyword"}
  }
}

【1】"dynamic":false。表示這個新欄位不會被索引,只是存儲到了_source。

【2】為了獲取這個新的欄位您必須reindex所有文檔。

搜索數據將找不到任何內容:

POST test/_search?filter_path=hits.total
{
  "query": {
    "match": {
      "flag": "foo"
    }
  }
}
{
  "hits" : {
    "total" : 0
  }
}

但是您可以用_update_by_query 請求獲得新的 mapping:

POST test/_update_by_query?refresh&conflicts=proceed
POST test/_search?filter_path=hits.total
{
  "query": {
    "match": {
      "flag": "foo"
    }
  }
}
{
  "hits" : {
    "total" : 1
  }
}

添加多個欄位時,也可以進行相同的操作。


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 一、引言 有了自動配置,springboot使web開發變得簡單,這個在springboot之旅中的第一篇中就有體現,實際的開發中當然不會這麼簡單,很多時候我們都需要自己去定製一些東西。web開發的東西比較多, 我們先掌握一些必要知識點,剩下的就是CRUD開發。 快速的創建一個springboot ...
  • 軟工作業2 ——實現一個能夠對文本文件中的單詞的詞頻進行統計的控制台程式 1.Github地址: https://github.com/wangshiyaoyao/WordCont 2.PSP表格 PSP2.1 Personal Software Process Stages 預估耗時(分鐘) 實際 ...
  • 異常 異常指的是程式中的不正常現象,一般異常都是由第三方數據的使用造成的。java中每種異常現象都會有一個對應的異常類。java對異常的處理方式就是終止程式。異常機制其實是為了幫助我們找到程式中的問題。異常指的並不是語法錯誤,語法錯了,編譯不通過,不會產生位元組碼文件,根本不能運行。 異常體系 jav ...
  • 今天我們繼續學習一下Numpy庫的學習 廢話不多說 ,開始講 比如我們現在想創建一個0-14這樣一個15位的數組 可以直接寫,但是很麻煩,Numpy中就給我們了一個方便創建的方法 numpy中有一個arange函數 運行這段代碼以後,可以得到如下結果 這裡我們可以看到,我先列印了一下,np.aran ...
  • 如果系統採用前後端分離的話,項目中就需要用到網關了,為了保證系統的安全性。 前後端項目簡單架構圖: 1. 基於網關實現白名單和黑名單攔截(防止惡意請求)、ip限流。 2. API介面實現Token授權驗證。 3. 使用MD5實現API介面驗證簽名,防止抓包篡改數據。 4. 實現API介面安全加密傳輸 ...
  • HashSet怎麼保證添加元素不重覆? HashSet是否允許null元素? HashSet是有序的嗎? HashSet是同步的嗎? 什麼是fail-fast? ...
  • 7、Multi Get API(Multi Get API) multi GET API 允許你一次性獲取多個文檔,你需要指定 數組,其中包含了所有你需要查詢的文檔,每個查詢結構至少包含索引,類型和文檔id。如果操作過程中遇到錯誤將會返回錯誤信息。返回的結果與 GET API 的結果結構類似。 如下 ...
  • Map集合 在Map集合中保存的數據為一組數據,其中:一個數據為key,另外一個數據為value。而key和value具備對應的關係,在集合中它們屬於一組(一對)數據。而每個key只能對應唯一的一個value值並且所有的key不能重覆。 但是其中的value值是可以重覆的。 Collection中的 ...
一周排行
    -Advertisement-
    Play Games
  • 示例項目結構 在 Visual Studio 中創建一個 WinForms 應用程式後,項目結構如下所示: MyWinFormsApp/ │ ├───Properties/ │ └───Settings.settings │ ├───bin/ │ ├───Debug/ │ └───Release/ ...
  • [STAThread] 特性用於需要與 COM 組件交互的應用程式,尤其是依賴單線程模型(如 Windows Forms 應用程式)的組件。在 STA 模式下,線程擁有自己的消息迴圈,這對於處理用戶界面和某些 COM 組件是必要的。 [STAThread] static void Main(stri ...
  • 在WinForm中使用全局異常捕獲處理 在WinForm應用程式中,全局異常捕獲是確保程式穩定性的關鍵。通過在Program類的Main方法中設置全局異常處理,可以有效地捕獲並處理未預見的異常,從而避免程式崩潰。 註冊全局異常事件 [STAThread] static void Main() { / ...
  • 前言 給大家推薦一款開源的 Winform 控制項庫,可以幫助我們開發更加美觀、漂亮的 WinForm 界面。 項目介紹 SunnyUI.NET 是一個基於 .NET Framework 4.0+、.NET 6、.NET 7 和 .NET 8 的 WinForm 開源控制項庫,同時也提供了工具類庫、擴展 ...
  • 說明 該文章是屬於OverallAuth2.0系列文章,每周更新一篇該系列文章(從0到1完成系統開發)。 該系統文章,我會儘量說的非常詳細,做到不管新手、老手都能看懂。 說明:OverallAuth2.0 是一個簡單、易懂、功能強大的許可權+可視化流程管理系統。 有興趣的朋友,請關註我吧(*^▽^*) ...
  • 一、下載安裝 1.下載git 必須先下載並安裝git,再TortoiseGit下載安裝 git安裝參考教程:https://blog.csdn.net/mukes/article/details/115693833 2.TortoiseGit下載與安裝 TortoiseGit,Git客戶端,32/6 ...
  • 前言 在項目開發過程中,理解數據結構和演算法如同掌握蓋房子的秘訣。演算法不僅能幫助我們編寫高效、優質的代碼,還能解決項目中遇到的各種難題。 給大家推薦一個支持C#的開源免費、新手友好的數據結構與演算法入門教程:Hello演算法。 項目介紹 《Hello Algo》是一本開源免費、新手友好的數據結構與演算法入門 ...
  • 1.生成單個Proto.bat內容 @rem Copyright 2016, Google Inc. @rem All rights reserved. @rem @rem Redistribution and use in source and binary forms, with or with ...
  • 一:背景 1. 講故事 前段時間有位朋友找到我,說他的窗體程式在客戶這邊出現了卡死,讓我幫忙看下怎麼回事?dump也生成了,既然有dump了那就上 windbg 分析吧。 二:WinDbg 分析 1. 為什麼會卡死 窗體程式的卡死,入口門檻很低,後續往下分析就不一定了,不管怎麼說先用 !clrsta ...
  • 前言 人工智慧時代,人臉識別技術已成為安全驗證、身份識別和用戶交互的關鍵工具。 給大家推薦一款.NET 開源提供了強大的人臉識別 API,工具不僅易於集成,還具備高效處理能力。 本文將介紹一款如何利用這些API,為我們的項目添加智能識別的亮點。 項目介紹 GitHub 上擁有 1.2k 星標的 C# ...