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),请选择一个较小的数字,因为太多的切片会影响性能。设置高于碎片数量的切片通常不会提高效率并增加开销。

删除性能随着可用资源的片数线性扩展。

查询或删除性能是否支配运行时取决于重新索引的文档和群集资源。

猜你喜欢

转载自blog.csdn.net/mine_1/article/details/85702481
API