用Query API删除 - shuiyuebingdian/ElasticSearch GitHub Wiki
Delete By Query API
最简单的用法是_delete_by_query在与查询匹配的每个文档上执行删除操作。这是API:
POST twitter/_delete_by_query
{
"query": {
"match": {
"message": "some message"
}
}
}
查询必须以query为键,查询条件为值传递给请求,与Search API相同的方式作。您也可以使用q 与搜索API相同的方式使用参数。
这将返回如下内容:
{
"took" : 147,
"timed_out": false,
"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,
"total": 119,
"failures" : [ ]
}
_delete_by_query在启动索引时获取索引的快照,并删除使用internal版本控制发现的索引。这意味着,如果在拍摄快照和处理删除请求之间更改文档,则会遇到版本冲突。当版本匹配时,将删除文档。
由于internal版本控制不支持将值0用作有效的版本号,因此无法使用删除版本等于零的文档,并且该文档 _delete_by_query将使请求失败。
在_delete_by_query执行期间,顺序执行多个搜索请求,以找到所有要删除的匹配文档。每次找到一批文档时,都会执行相应的批量请求以删除所有这些文档。如果搜索或批量请求被拒绝,则_delete_by_query 依靠默认策略重试被拒绝的请求(最多10次,并以指数方式退回)。达到最大重试次数限制将导致_delete_by_query 中止,并且所有失败都将在failures响应中返回。已经执行的删除仍然会保留。换句话说,该过程不会回滚,只会中止。当第一个失败导致中止时,失败的批量请求返回的所有失败都将在failures 元件; 因此,可能会有很多失败的实体。
如果您想计算版本冲突而不是使它们中止conflicts=proceed,请在url或"conflicts": "proceed"请求正文中进行设置。
回到API格式,您可以限制_delete_by_query为单一类型。这只会tweet从twitter索引中删除文档:
POST twitter/tweet/_delete_by_query?conflicts=proceed
{
"query": {
"match_all": {}
}
}
也可以一次删除多个索引和多种类型的文档,就像搜索API一样:
POST twitter,blog/tweet,post/_delete_by_query
{
"query": {
"match_all": {}
}
}
如果提供,routing则将路由复制到滚动查询,将过程限制为与该路由值匹配的分片:
POST twitter/_delete_by_query?routing=1
{
"query": {
"range" : {
"age" : {
"gte" : 10
}
}
}
}
默认情况下,_delete_by_query使用滚动批处理1000。您可以在URL中使用scroll_size参数更改批处理大小: POST twitter/_delete_by_query?scroll_size=5000 { "query": { "term": { "user": "kimchy" } } }
URL参数
除了标准的参数,如pretty,通过查询API删除也支持refresh,wait_for_completion,wait_for_active_shards,和timeout。
refresh请求完成后,发送将会刷新查询所涉及的所有分片。这与Delete API的refresh 参数不同,后者仅导致接收到删除请求的分片被刷新。
如果请求包含,wait_for_completion=false则Elasticsearch将执行一些预检检查,启动请求,然后返回task ,可与Tasks API 一起使用来取消或获取任务的状态。Elasticsearch还将在创建此任务的记录上作为文档.tasks/task/${taskId}。您可以根据自己的喜好保留或删除此文件。完成后,将其删除,以便Elasticsearch可以回收其使用的空间。
wait_for_active_shards控制在进行请求之前必须处于活动状态的分片副本数。有关 详细信息,请参见此处。timeout控制每个写入请求等待不可用的碎片变为可用的时间。两者都在Bulk API中完全一样地工作 。
requests_per_second可以被设置为任何正十进制数(1.4,6, 1000等)和节气门速率_delete_by_query通过填充每批用的等待时间问题的删除操作的批次。将设置requests_per_second为可以禁用节流-1。
节流是通过在批处理之间等待来完成的,以便_delete_by_query可以给内部使用的滚动 指定一个超时,该超时要考虑填充。填充时间是批大小除以requests_per_second和所花费的时间之间的差。默认情况下,批处理大小为1000,因此如果将requests_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。
反应体 JSON响应如下所示:
{
"took" : 639,
"deleted": 0,
"batches": 1,
"version_conflicts": 2,
"retries": 0,
"throttled_millis": 0,
"failures" : [ ]
}
took
从整个操作开始到结束的毫秒数。
deleted
成功删除的文档数。
batches
由delete by查询拉回的滚动响应数。
version_conflicts
被查询删除导致的版本冲突数量。
retries
通过查询删除以响应已满队列的重试次数。
throttled_millis
要求遵守的毫秒数requests_per_second。
failures
所有索引失败的数组。如果这是非空的,则请求由于这些失败而中止。有关conflicts如何防止版本冲突中止操作的信息,请参阅。
与Task API配合使用
您可以使用Task API获取所有正在运行的按查询删除请求的状态 :
GET _tasks?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" : ""
}
}
}
}
}
该对象包含实际状态。就像响应json加上重要的total字段一样。total是重新索引期望执行的操作总数。您可以通过添加估计的进展updated,created以及deleted多个领域。当它们的总和等于total字段时,请求将结束。
,您可以使用任务ID直接查找任务:
GET /_tasks/taskId:1
该API的优势在于它与之集成wait_for_completion=false 以透明地返回已完成任务的状态。如果任务已完成并wait_for_completion=false设置在任务上,则它将返回 results或error字段。此功能的成本是在wait_for_completion=false创建的文档 .tasks/task/${taskId}。删除该文档由您决定。
与Cancel Task API一起使用 可以使用Task Cancel API取消所有“按查询删除”功能:
POST _tasks/task_id1/_cancel
在task_id可以使用上述任务的API被发现。
取消应该很快发生,但可能需要几秒钟。上面的任务状态API将继续列出任务,直到被唤醒以取消自身为止。
重新调节
requests_per_second可以使用_rethrottleAPI 通过查询在运行的删除中更改的值:
POST _delete_by_query/task_id:1/_rethrottle?requests_per_second=-1
在task_id可以使用上述任务的API被发现。
就像在_delete_by_queryAPI requests_per_second 上进行设置一样,可以-1禁用限制或任何十进制数字,1.7或12将其限制为该级别。重新调整以加快查询的速度会立即生效,但重新调整以使查询的速度缓慢将在完成当前批处理后生效。这样可以防止滚动超时。
手动切片
按查询删除支持切片滚动,使您可以相对轻松地手动并行化过程:
POST 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
}
}
}
}
结果total是这样的:
{
"hits": {
"total": 0
}
}
自动切片
您还可以使用“ 切片滚动”让“按查询删除”自动并行化 以切片_uid:
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
}
}
}
}
结果total是这样的:
{
"hits": {
"total": 0
}
}
添加slices到_delete_by_query可以自动完成上一节中使用的手动过程,创建子请求,这意味着它有一些怪癖:
- 您可以在Tasks API中看到这些请求 。这些子请求是带有的请求任务的“子”任务slices。
- 获取请求的任务状态slices仅包含已完成切片的状态。
- 这些子请求可分别用于取消和限制操作。
- 重新限制请求slices将按比例重新限制未完成的子请求。
- 用取消请求slices将取消每个子请求。
- 由于slices每个子请求的性质,将无法获得完全均匀的文档部分。将处理所有文档,但是某些切片可能比其他切片大。期望更大的切片具有更均匀的分布。
- 带有requests_per_second和size带有请求的 参数与slices 每个子请求成比例地分布。结合以上关于分布不均的观点,您应该得出结论,使用 sizewith slices可能不会完全对size文档_delete_by_query进行编辑。
- 每个子请求都将获得源索引的快照略有不同的快照,尽管它们都是在大约同一时间拍摄的。
挑选切片数
此时,我们slices对使用的数量提出了一些建议(max如果手动并行化,则使用slice API中的参数):
- 不要使用大量数字。500会造成相当大的CPU抖动。
- 从查询性能的角度来看,在源索引中使用分片数量的一些倍数会更有效。
- 从查询性能的角度来看,使用与源索引中的数量一样多的分片是最有效的。
- 索引性能应在可用资源范围内线性扩展,数量为slices。
- 索引还是查询性能在该过程中占主导地位,取决于许多因素,例如要重新建立索引的文档以及正在执行重新建立索引的集群。