Elasticsearch java API批量删除不起作用

时间:2015-09-03 22:59:46

标签: java elasticsearch

我正在尝试批量删除其ID来自先前搜索的文档。确定删除候选文档的查询产生了所需的结果(数千条记录),但批量删除一次只删除10条记录,即使我正在提供原始查询的所有结果;

Client client = node.client();
BulkRequestBuilder bulkRequest = client.prepareBulk();

SearchResponse deletes = client.prepareSearch("my_index")
        .setTypes("my_doc_type")
        .setSearchType(SearchType.DFS_QUERY_THEN_FETCH)
        .setQuery(boolQuery().mustNot(termQuery("tId", transactionId)))
        .execute()
        .actionGet();

long deleteHits = deletes.getHits().getTotalHits();

if (deleteHits > 0) {

    logger.info("Preparing to delete (" + deleteHits + ") " +
            "documents from index");

    Arrays.asList(deletes.getHits().getHits()).stream().forEach(h ->
            bulkRequest.add(client.prepareDelete()
                .setIndex("my_index")
                .setType("my_doc_type")
                .setId(h.getId())));
    }

    BulkResponse bulkResponse = bulkRequest.execute().actionGet();

    if (bulkResponse.hasFailures()) {
        throw new RuntimeException(bulkResponse.buildFailureMessage());
    }

}

2 个答案:

答案 0 :(得分:1)

默认情况下,搜索响应仅返回前10个结果。因此,虽然deletes .getHits().getTotalHits()可以是数千甚至数百万,但deletes.getHits().getHits()的大小永远不会超过您在请求的size参数中指定的大小,默认情况下为10。 / p>

一种天真的方法是尝试通过更改from参数来使用普通搜索来尝试分页。但是,这可能导致丢失删除某些记录,因为每个命令将执行新的搜索,并且由于删除先前搜索中的记录,下一次搜索的结果可能与前一次搜索相比发生偏移。

正确的方法是使用专门的scan and scroll search分页投掷记录。这种类型的搜索将使调用之间的结果保持一致。这种方法的一个例子可以在v2.0中可用的delete by query插件中找到。

我还需要注意,虽然以前版本的elasticsearch中存在delete by query功能,但它似乎是您问题的最简单的解决方案,但我仍然建议使用扫描/滚动,因为{{ 3}}在v2.0之前的查询API实现中的现有删除。

答案 1 :(得分:0)

deletes.getHits().getTotalHits为您提供搜索的总点击次数,但SearchResponse deletes不包含所有搜索结果。 你需要对它进行分页。

您需要使用类似的内容来定义分页

client.prepareSearch("my_index").setFrom(int from).setSize(int pageSize);