10、delete_by_query API
原文地址:https://www.elastic.co/guide/en/elasticsearch/reference/current/docs-delete-by-query.html
elasticsearch版本:6.5
目錄地址:https://blog.csdn.net/mine_1/article/details/85623429
用_delete_by_query介面可以按條件刪除指定的文件,API如下:
POST twitter/_delete_by_query { "query":{ "match":{ "message":"some message" } } }
得到的響應如下:
{ "took":147, "time_out":false, "deleted":149, "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": 119, "failures" : [ ] }
_delete_by_query在索引啟動時獲取索引快照,並使用internal版本控制刪除找到的內容。這意味著,如果文件在拍攝快照的時間和處理刪除請求的時間之間發生更改,則會出現版本衝突。當版本匹配時,文件將被刪除。注意:internal版本不支援0,所以當版本等於0是不能用_delete_by_query刪除。
在_delete_by_query執行過程中,將按順序執行多個搜尋請求,以查詢所有要刪除的匹配文件。每次找到一批文件時,都會執行相應的批量請求來刪除所有這些文件。如果搜尋或批量請求被拒絕,按_delete_by_query的預設策略來重試被拒絕的請求(最多10次,速度呈指數下降)。達到最大重試次數限制會導致_delete_by_query操作中止,並在響應中返回所有失敗資訊。已執行的刪除操作仍然保持不變。換句話說,程序不會回滾,只會中止。當第一個失敗導致中止時,由失敗的批量請求返回的所有失敗都會在failures元素中返回;因此,可能會有相當多失敗的實體。
如果您想計算版本衝突而不是讓它們中止,那麼在URL上設定conflicts=proceed或在請求正文中設定conflicts:proceed。
如下面的請求將會刪除twitter索引裡面的tweets:
POST twitter/_doc/_detele_by_query?conflicts=proceed
{
"query":{
"match_all":{}
}
}
也可以一次刪除多個索引和型別裡面的文件,如:
POST twitter,blog/_docs,post/_delete_by_query
{
"query":{
"match_all":{}
}
}
如果提供了routing,那麼routing資訊也會被放到查詢過程中,只刪除滿足routing條件的分片中的文件:
POST twitter/_delete_by_query?routing=1
{
"query":{
"range":{
"age":{
"gte":10
}
}
}
}
預設情況下,_delete_by_query使用的滾動批次為1000。您可以使用 scroll_size URL引數更改大小:
POST twitter/_delete_by_query?scroll_size=5000
{
"query":{
"term":{
"user":"kimchy"
}
}
}
(1)URL引數
除了支援通用引數如pretty等,_delete_by_query還支援refresh、wait_for_completion、wait_for_active_shards、timeout和scroll引數。
- refresh引數:執行完刪除操作後重新整理_delete_by_query中查詢涉及的分片。與delete API不同,delete API只會重新整理接收到刪除請求的分片。refresh引數不支援wait_for。
- wait_for_completion:如果請求中wait_for_completion=false,那麼elasticsearch將會執行預檢查、執行請求,然後返回可與任務API一起使用的任務,以取消或獲取任務的狀態。elasticsearch還將在.task/task/${taskId}處建立此任務的記錄文件。您可以根據需要保留或刪除該文件。用完刪除後,elasticsearch可以回收其佔用的空間。
- wait_for_active_shards:控制在執行請求之前必須有多少個分片是啟用的。
- timeout:控制每個請求等待不可用的分片的時間。用_delete_by_query使用滾動查詢是,您也可以通過設定scroll引數來控制search context保持活動的時間。如scroll=10m,預設為5分鐘。
- requests_per_second:可以設定成任意正數(如1.4,6,1000等),並且通過設定等待的時間來控制_delete_by_query批量操作執行刪除操作的速率。設定requests_per_second設定為-1表示停用該限制。
速率限制是通過在批量處理之間等待來完成的,這樣就可以為_delete_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 - 0.5 seconds = 1.5seconds
由於該批是作為_bulk請求發出的,因此大批量的請求將導致ElasticSearch建立多個請求,然後在啟動下一個集合之前等待一段時間。這是“急躁”而不是“平穩”。預設值為-1。
(2)響應體
得到的JSON格式的響應如:
{
"took" : 147,
"timed_out": false,
"total": 119,
"deleted": 119,
"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:整個操作消耗的時間,但是是milliseconds
- timed_out:如果在執行查詢結果的刪除操作中有超時,那麼這個標識將會返回true
- total:正確執行操作的文件的數量
- deleted:正確刪除文件的數量
- batches : 回滾數
- version_conflicts:操作過程中遇到的版本衝突數
- noops:_delete_by_query時這個值一直是0,之所以存在是因為_delete_by_query、update_by_query、reindex APIs都返回縣共同的結構。
- retries:在操作過程中重試的次數,bulk是批量刪除操作重複嘗試的次數,search是查詢的重複嘗試次數
- throttled_millis:滿足requests_per_second引數的請求休眠的毫秒數
- requests_per_second:在操作過程中,每秒執行的請求數
- throttled_until_millis:_delete_by_query操作中這個值一直是0
- failures:執行失敗的陣列,包含在執行過程中任何不可恢復的錯誤。如果這個陣列不是空的,那麼請求會因為這些失敗而中止。_delete_by_query是使用批處理實現的,任何失敗都會導致整個進行中止。可以只用conflicts引數來阻止reindex造成的操作中止。
(3)Task API
您可以使用任務API獲取任何正在執行的_delete_by_query請求的狀態:
GET _takes?detailed=true&actions=*/delete/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/delete/byquery",
"status" : {
"total" : 6154,
"updated" : 0,
"created" : 0,
"deleted" : 3500,
"batches" : 36,
"version_conflicts" : 0,
"noops" : 0,
"retries": 0,
"throttled_millis": 0
},
"description" : ""
}
}
}
}
}
有了task id就可以直接檢視指定的task:
GET /_tasks/r1A2WoRbTwKZ516z6NEs5A:36619
整個介面可以與wait_for_comletion=false整合使用,以便能清晰的返回已完成任務的狀態。如果任務已經完成,並且wait_for_completion=false,那麼請求將會返回結果或是錯誤欄位。此功能的成本是當wait_for_completion=false時在.tasks/task/${taskId}目錄下建立文件。您可以根據需要刪除該文件。
(4)Cancel Task API
任何delete_by_query操作都可以利用task cancel API進行刪除,如:
POST _tasks/r1A2WoRbTwKZ516z6NES5a:36619/_cancel
取消應該執行很快,但可能需要幾秒鐘。上面的任務狀態API將繼續列出該任務,直到它被喚醒以取消自身。
(5)Rethrottling
正在執行的請求中,上述的request_per_second引數可以通過_rethrotted API進行修改:
POST _delete_by_query/r1A2WoRbTwKZ516z6NEs5A:36619/_rethrottle?requests_per_second=-1
request_per_second可以設定為-1來禁用限制,也可以是任何十進位制數如1.7或是12來限制該級別。加快查詢速度的設定將會立即生效,但是減慢查詢速度的設定將在完成當前批處理後生效,這樣可以防止回滾超時。
(6)Slicing
delete_by_query支援sliced scroll來使刪除操作並行進行,這能提高效率並且能提供一種方便的方法將請求分解為較小的部分。
Manually slicing
通過為每個請求提供一個分片ID和切片總數,手動將_delete_by_query操作進行分解:
OST twitter/_delete_by_query
{
"slice": {
"id": 0,
"max": 2
},
"query": {
"range": {
"likes": {
"lt": 10
}
}
}
}
POST twitter/_delete_by_query
{
"slice": {
"id": 1,
"max": 2
},
"query": {
"range": {
"likes": {
"lt": 10
}
}
}
}
可以這樣驗證:
GET _refresh
POST twitter/_search?size=0&filter_path=hits.total
{
"query": {
"range": {
"likes": {
"lt": 10
}
}
}
}
得到的響應如下:
{
"hits":{
"total":0
}
}
Automatic slicing
也可以進行自動分解,通過設定slices引數來指定使用分片的個數:
POST twitter/_delete_by_query?refresh&slices=5
{
"query": {
"range": {
"likes": {
"lt": 10
}
}
}
}
可以這樣驗證:
POST twitter/_search?size=0&filter_path=hits.total
{
"query": {
"range": {
"likes": {
"lt": 10
}
}
}
}
得到的響應如:
{
"hits":{
"total":0
}
}
將slices設定為auto將允許ElasticSearch選擇要使用的切片數。此設定將每個碎片使用一個切片,直至達到某個限制。如果存在多個源索引,它將根據具有最小碎片數的索引選擇切片數。
如果自動切片,將切片設定為自動將為大多數索引選擇一個合理的數字。如果您是手動切片或調整自動切片,請使用以下準則。
當切片數等於索引中的碎片數時,查詢效能最有效。如果該數字很大(例如,500),請選擇一個較小的數字,因為太多的切片會影響效能。設定高於碎片數量的切片通常不會提高效率並增加開銷。
刪除效能隨著可用資源的片數線性擴充套件。
查詢或刪除效能是否支配執行時取決於重新索引的文件和群集資源。