delete_by_query 做什么
delete_by_query 按查询条件删除文档,同时保留索引结构与 mapping,适合删除「部分数据」而不是整个索引。它同样支持切片并行与冲突处理策略,返回删除数量、版本冲突与批次统计。删除量极大时索引里会留下大量墓碑段,要等合并才能回收空间。
基本信息
| 接口 | POST /<index>/_delete_by_query |
|---|---|
| 常用参数 | conflicts=proceed、slices=auto、wait_for_completion=false |
| 返回计数 | deleted、version_conflicts、batches、failures |
| 空间回收 | 删除只做标记,磁盘要等段合并后才真正释放 |
| 替代方案 | 按时间切索引后直接删整个索引更省资源 |
典型使用场景
- 清理超过保留期的数据,但索引还要继续写入
- 按业务条件删除错误数据,例如误导入的批次
- 删除命中敏感词或不合规内容的文档
- 收缩数据量:把临时测试数据从生产索引里剔除
- 先用 _count 预估范围,再做小批量删除以降低单次压力
常用写法
常用写法
# 删除 90 天前的数据
POST /logs-2024/_delete_by_query?conflicts=proceed
{ "query": { "range": { "@timestamp": { "lt": "now-90d" } } } }
# 先核对命中数量,避免误删
GET /logs-2024/_count
{ "query": { "range": { "@timestamp": { "lt": "now-90d" } } } }
# 大批量删除改为异步执行
POST /logs-2024/_delete_by_query?wait_for_completion=false&slices=auto
{ "query": { "term": { "batch": "bad-2026-10-13" } } }
# 删除后回收空间:对只读索引做段合并
POST /logs-2024/_forcemerge?only_expunge_deletes=true返回计数读法
| 计数 | 含义 | 异常信号 |
|---|---|---|
| deleted | 成功删除的文档数 | 与 _count 预估差距大说明条件不稳定 |
| version_conflicts | 版本冲突次数 | 使用跳过策略时要核对是否符合预期 |
| batches | 执行批次数量 | 批次数极大说明单批太小、整体耗时长 |
| failures | 失败明细数组 | 非空时逐条看原因再重跑 |
定期清理历史数据优先用 ILM 的 delete 阶段,或按时间切索引后直接删整个索引;逐条删除需要重写段,资源开销比删索引大得多。
删除任务同样按快照推进,执行期间新写入且符合条件的数据不会被删;周期清理任务要么接受这种漏删,要么在下一轮调度时重新执行一次同条件删除。