浏览所有文档并批量更新其中一些

时间:2016-02-13 14:48:28

标签: elasticsearch jest

我使用Jest client for Elastic来浏览文档索引以更新一个字段。我的工作流程是使用分页运行一个空查询,看看我是否可以计算额外字段。如果可以的话,我会在一次批量更新中更新相关文档。

伪代码

private void process() {
    int from = 0
    int size = this.properties.batchSize
    boolean moreResults = true
    while (moreResults) {
        moreResults = handleBatch(from, this.properties.batchSize)
        from += size
    }
}

private boolean handleBatch(int from, int size) {
    log.info("Processing records $from to " + (from + size))
    def result = search(from, size)
    if (result.isSucceeded()) {
        // Check each element and perform an upgrade
    }
    // return true if the query returned at least one item
}

private SearchResult search(int from, int size) {
    String query =
            '{ "from": ' + from + ', ' +
                    '"size": ' + size + '}'


    Search search = new Search.Builder(query)
            .addIndex("my-index")
            .addType('my-document')
            .build();
    jestClient.execute(search)
}

我没有任何错误,但是当我多次运行批处理时,它看起来就像找到" new"要升级的文档,而文档总数没有变化。我怀疑已经多次处理了更新的文档,我可以通过检查已处理的ID来确认。

如何运行查询以便原始文档处理完毕并且任何更新都不会干扰它?

1 个答案:

答案 0 :(得分:1)

您需要运行scroll search query,而不是运行普通搜索(即使用size + // 1. Initiate the scroll request Search search = new Search.Builder(searchSourceBuilder.toString()) .addIndex("my-index") .addType("my-document") .addSort(new Sort("_doc")) .setParameter(Parameters.SIZE, size) .setParameter(Parameters.SCROLL, "5m") .build(); JestResult result = jestClient.execute(search); // 2. Get the scroll_id to use in subsequent request String scrollId = result.getJsonObject().get("_scroll_id").getAsString(); // 3. Issue scroll search requests until you have retrieved all results boolean moreResults = true; while (moreResults) { SearchScroll scroll = new SearchScroll.Builder(scrollId, "5m") .setParameter(Parameters.SIZE, size).build(); result = client.execute(scroll); def hits = result.getJsonObject().getAsJsonObject("hits").getAsJsonArray("hits"); moreResults = hits.size() > 0; } )。主要区别在于滚动将冻结文档的给定快照(在查询时)并查询它们。无论第一次滚动查询后发生什么变化,都不会被考虑。

使用Jest,您需要修改代码,使其看起来更像这样:

process

您需要使用上述代码修改handleBatchequals()方法。它应该是直截了当的,如果没有,请告诉我。