Update by Query

Update by Query #

Update by Query 对所有匹配查询条件的文档执行更新操作。 常用于批量修改字段值、数据迁移补丁、通过脚本做批量计算等场景。

内部流程:scroll 遍历匹配文档 → 逐批执行 bulk update → 返回统计结果。


请求格式 #

POST /<index>/_update_by_query

路径参数 #

参数必需说明
<index>目标索引,支持逗号分隔多索引和通配符

查询参数 #

参数类型默认值说明
refreshbooleanfalse操作完成后是否刷新受影响的分片
timeouttime1m超时时间
wait_for_completionbooleantruetrue 时同步等待完成后返回结果;为 false 时立即返回 task ID,可通过 Task API 查询进度
wait_for_active_shardsstring操作前需要的活跃分片数量
requests_per_secondfloat无限制每秒请求数限制(流量控制)。-1 = 不限制
slicesint/string1并行切片数。"auto" = 自动按分片数拆分
scrolltimescroll 上下文存活时间(如 5m
scroll_sizeint1000每批 scroll 获取的文档数
conflictsstringabort版本冲突处理方式:abort = 遇到冲突即中止;proceed = 跳过冲突继续执行
max_docsint全部最多处理的文档数量
pipelinestring对匹配文档执行的 Ingest Pipeline
search_timeouttime搜索阶段超时
qstring简单查询字符串(替代请求体中的 query
dfstringq 参数的默认字段
default_operatorstringORq 参数的默认运算符
analyzerstringq 参数使用的分析器
analyze_wildcardbooleanfalse是否分析通配符
lenientboolean宽松解析模式
routingstring路由值
preferencestring查询偏好
terminate_afterint0每分片最多处理的文档数(0 = 不限制)
expand_wildcardsstringopen通配符展开:openclosedhiddenallnone
ignore_unavailablebooleanfalse忽略不存在的索引
allow_no_indicesbooleantrue允许通配符不匹配任何索引

请求体 #

{
  "query": { ... },
  "script": {
    "source": "...",
    "lang": "painless",
    "params": { ... }
  },
  "max_docs": 1000,
  "conflicts": "proceed"
}
字段类型说明
queryobject筛选条件,语法同 Query DSL。省略时匹配所有文档
scriptobject更新脚本。通过 ctx._source 访问和修改文档字段
max_docsint最多处理的文档数
conflictsstring冲突处理策略

不提供 script 时,Update by Query 仅对匹配文档触发重建索引(re-index in place),常用于 mapping 变更后重新分析已有文档。


示例 #

基本用法:给所有匹配文档添加字段 #

POST /website/_update_by_query
{
  "query": {
    "term": { "status": "draft" }
  },
  "script": {
    "source": "ctx._source.status = 'published'",
    "lang":   "painless"
  }
}

不带脚本:重建索引 #

mapping 变更后,对所有文档触发重新索引:

POST /website/_update_by_query
{
  "query": { "match_all": {} }
}

流量控制 #

限制每秒处理 500 条,避免影响线上查询:

POST /website/_update_by_query?requests_per_second=500&conflicts=proceed
{
  "query": { "match_all": {} },
  "script": {
    "source": "ctx._source.migrated = true",
    "lang":   "painless"
  }
}

异步执行 #

大批量更新时,使用异步模式:

POST /website/_update_by_query?wait_for_completion=false
{
  "query": { "match_all": {} },
  "script": {
    "source": "ctx._source.version = 2",
    "lang":   "painless"
  }
}

响应返回 task ID:

{
  "task": "node_id:task_id"
}

通过 Task API 查询进度:

GET /_tasks/node_id:task_id

并行切片 #

使用 slices=auto 按分片数自动并行处理:

POST /website/_update_by_query?slices=auto
{
  "query": { "match_all": {} },
  "script": {
    "source": "ctx._source.processed = true",
    "lang":   "painless"
  }
}

通过 Pipeline 更新 #

利用已有 Ingest Pipeline 处理匹配文档:

POST /website/_update_by_query?pipeline=my_pipeline
{
  "query": { "match_all": {} }
}

响应字段 #

{
  "took":                 147,
  "timed_out":            false,
  "total":                5,
  "updated":              5,
  "deleted":              0,
  "batches":              1,
  "version_conflicts":    0,
  "noops":                0,
  "retries": {
    "bulk":   0,
    "search": 0
  },
  "failures": []
}
字段说明
took操作耗时(毫秒)
total匹配的文档总数
updated成功更新的文档数
deleted被脚本删除的文档数(脚本设置 ctx.op = "delete" 时)
version_conflicts版本冲突次数
noops无操作次数(脚本设置 ctx.op = "noop" 时)
batchesscroll 批次数
retries.bulkbulk 重试次数
retries.searchsearch 重试次数
failures失败详情数组

脚本中的操作控制 #

在脚本中可以通过设置 ctx.op 控制每条文档的处理方式:

ctx.op行为
"index"默认值,更新文档
"noop"跳过该文档,不做任何写入
"delete"删除该文档
POST /website/_update_by_query
{
  "query": { "match_all": {} },
  "script": {
    "source": "if (ctx._source.views < 10) { ctx.op = 'noop' } else { ctx._source.popular = true }",
    "lang": "painless"
  }
}

参考导航 #

需求参见
单条文档更新Update API
按查询删除文档Delete by Query
跨索引迁移数据Reindex
乐观并发控制并发控制与版本