1. 程式人生 > >10、delete_by_query API

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),請選擇一個較小的數字,因為太多的切片會影響效能。設定高於碎片數量的切片通常不會提高效率並增加開銷。

刪除效能隨著可用資源的片數線性擴充套件。

查詢或刪除效能是否支配執行時取決於重新索引的文件和群集資源。