You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过Elasticsearch Java API记录DeleteByQuery处理/删除的所有文档?

记录DeleteByQuery处理/删除的具体文档

要获取DeleteByQuery操作中所有被处理/删除的具体文档信息,需要调整请求配置并遍历响应结果,以下是两种可行方案:

方案一:直接通过DeleteByQueryResponse获取文档信息

通过配置DeleteByQueryRequest开启源数据获取,执行后遍历响应中的每个操作项,即可拿到单个文档的详情:

步骤1:配置DeleteByQueryRequest

// 创建删除请求,指定目标索引
DeleteByQueryRequest deleteRequest = new DeleteByQueryRequest("your_target_index");
// 设置删除的查询条件,这里以匹配所有文档为例
deleteRequest.setQuery(QueryBuilders.matchAllQuery());
// 开启获取文档源数据,可指定需要返回的字段(第一个参数为包含字段,第二个为排除字段)
deleteRequest.setFetchSource(new String[]{"_id", "name", "create_time"}, null);

步骤2:执行请求并遍历结果

BulkByScrollResponse bulkResponse = client.deleteByQuery(deleteRequest, RequestOptions.DEFAULT);

// 遍历所有被处理的文档
for (BulkItemResponse item : bulkResponse.getItems()) {
    String docIndex = item.getIndex();
    String docId = item.getId();
    
    if (item.isFailed()) {
        // 处理文档操作失败的情况
        BulkItemResponse.Failure failure = item.getFailure();
        System.out.printf("文档处理失败 - 索引: %s, ID: %s, 原因: %s%n", docIndex, docId, failure.getMessage());
        continue;
    }

    // 获取文档源数据(需提前开启fetchSource)
    Map<String, Object> docSource = item.getResponse().getGetResult().getSource();
    // 判断操作类型是否为删除
    boolean isDeleted = item.getOpType() == DocWriteRequest.OpType.DELETE;

    System.out.printf("已处理文档 - 索引: %s, ID: %s, 操作类型: %s, 源数据: %s%n",
            docIndex, docId, isDeleted ? "删除" : "其他", docSource);
}

// 保留总数统计
System.out.println("Total documents processed: " + bulkResponse.getTotal());
System.out.println("Total documents deleted: " + bulkResponse.getDeleted());

注意:如果文档数据量较大,返回完整源数据会占用较多内存,建议仅指定业务需要的字段,避免性能问题。

方案二:先查询记录再执行删除

如果需要先完整记录待删除文档信息,再执行删除操作,可以通过Scroll查询先获取所有待删文档,再批量删除:

步骤1:Scroll查询待删除文档并记录

// 创建查询请求
SearchRequest searchRequest = new SearchRequest("your_target_index");
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
// 设置与DeleteByQuery一致的查询条件
sourceBuilder.query(QueryBuilders.matchAllQuery());
sourceBuilder.size(1000); // 每次Scroll拉取的文档数量
searchRequest.source(sourceBuilder);
searchRequest.scroll(TimeValue.timeValueMinutes(1)); // 设置Scroll有效期

SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);
String scrollId = searchResponse.getScrollId();
SearchHit[] hits = searchResponse.getHits().getHits();

List<String> toDeleteDocIds = new ArrayList<>();

// 遍历所有Scroll结果
while (hits != null && hits.length > 0) {
    for (SearchHit hit : hits) {
        String docIndex = hit.getIndex();
        String docId = hit.getId();
        Map<String, Object> docSource = hit.getSourceAsMap();
        
        System.out.printf("待删除文档 - 索引: %s, ID: %s, 源数据: %s%n", docIndex, docId, docSource);
        toDeleteDocIds.add(docId);
    }

    // 续拉取下一批数据
    SearchScrollRequest scrollRequest = new SearchScrollRequest(scrollId);
    scrollRequest.scroll(TimeValue.timeValueMinutes(1));
    searchResponse = client.scroll(scrollRequest, RequestOptions.DEFAULT);
    scrollId = searchResponse.getScrollId();
    hits = searchResponse.getHits().getHits();
}

// 清理Scroll上下文,释放资源
ClearScrollRequest clearScrollRequest = new ClearScrollRequest();
clearScrollRequest.addScrollId(scrollId);
client.clearScroll(clearScrollRequest, RequestOptions.DEFAULT);

步骤2:执行批量删除

DeleteByQueryRequest deleteRequest = new DeleteByQueryRequest("your_target_index");
// 根据记录的ID执行删除
deleteRequest.setQuery(QueryBuilders.idsQuery().addIds(toDeleteDocIds.toArray(new String[0])));

BulkByScrollResponse bulkResponse = client.deleteByQuery(deleteRequest, RequestOptions.DEFAULT);
System.out.println("Total documents deleted: " + bulkResponse.getDeleted());

这种方案更适合需要在删除前做数据校验、备份的场景,同时避免大数量下DeleteByQuery返回过多数据的性能问题。

内容的提问来源于stack exchange,提问作者KiKo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.20 15:32:03