ElasticSearch6.X版本Java Api中文詳解(七)之Update By Query API解析

updateByQuery最簡單的用法是更新索引中的每個文檔,而無需更改源。這種用法允許拾取新屬性或另一個在線映射更改。

UpdateByQueryRequestBuilder updateByQuery = UpdateByQueryAction.INSTANCE.newRequestBuilder(client);
updateByQuery.source("source_index").abortOnVersionConflict(false);
BulkByScrollResponse response = updateByQuery.get();

對updateByQuery API的調用首先獲取索引的快照,對使用內部版本控制的任何文檔進行索引。

注意:當一個文檔在快照的時間和索引請求過程的時間之間發生變化時,就會發生版本衝突。.

當版本匹配時,updateByQuery會更新文檔並增加版本號。

所有更新和查詢失敗都會導致updateByQuery中止。這些故障可以從bulk by scroll response getinde方法中獲得。任何成功的更新都是保留的,不會回滾。當第一個故障導致中止時,響應包含失敗的批量請求所產生的所有故障。


爲了防止版本衝突導致updateByQuery中止,設置終止衝突(false)。第一個例子是這樣做的,因爲它試圖獲取一個在線映射更改,而版本衝突意味着在updateByQuery的開始和試圖更新文檔的時間之間更新了相互衝突的文檔。這很好,因爲更新將會獲得在線地圖更新。

UpdateByQueryRequestBuilder API支持過濾更新後的文檔,限制更新的文檔總數,並使用腳本更新文檔:

UpdateByQueryRequestBuilder updateByQuery = UpdateByQueryAction.INSTANCE.newRequestBuilder(client);
updateByQuery.source("source_index")
    .filter(QueryBuilders.termQuery("level", "awesome"))
    .size(1000)
    .script(new Script(ScriptType.INLINE, "ctx._source.awesome = 'absolutely'", "painless", Collections.emptyMap()));
BulkByScrollResponse response = updateByQuery.get();

UpdateByQueryRequestBuilder還允許直接訪問用來選擇文檔的查詢。您可以使用這個訪問來改變默認的滾動大小,或者對匹配文檔的請求進行修改。

UpdateByQueryRequestBuilder updateByQuery = UpdateByQueryAction.INSTANCE.newRequestBuilder(client);
updateByQuery.source("source_index")
    .source().setSize(500);
BulkByScrollResponse response = updateByQuery.get();

您還可以將大小與排序合併,以限制更新的文檔:

UpdateByQueryRequestBuilder updateByQuery = UpdateByQueryAction.INSTANCE.newRequestBuilder(client);
updateByQuery.source("source_index").size(100)
    .source().addSort("cat", SortOrder.DESC);
BulkByScrollResponse response = updateByQuery.get();

除了改變文檔的源代碼字段之外,您還可以使用一個腳本來更改動作,類似於更新API:

UpdateByQueryRequestBuilder updateByQuery = UpdateByQueryAction.INSTANCE.newRequestBuilder(client);
updateByQuery.source("source_index")
    .script(new Script(
        ScriptType.INLINE,
        "if (ctx._source.awesome == 'absolutely) {"
            + "  ctx.op='noop'"
            + "} else if (ctx._source.awesome == 'lame') {"
            + "  ctx.op='delete'"
            + "} else {"
            + "ctx._source.awesome = 'absolutely'}",
        "painless",
        Collections.emptyMap()));
BulkByScrollResponse response = updateByQuery.get();

正如在更新API中一樣,您可以設置ctx的值。op改變執行的操作:

無操作

ctx設置。如果你的腳本沒有任何變化,op=“noop”。updateByQuery operaton會從更新中刪除該文檔。這種行爲增加了響應體中的noop計數器。

刪除

ctx設置。如果您的腳本決定必須刪除該文檔,那麼op=“delete”。刪除將在響應主體中被刪除的計數器中報告。

設置ctx。op對任何其他值都產生一個錯誤。在ctx中設置任何其他字段會產生一個錯誤。

這個API不允許您移動它所觸及的文檔,只是修改它們的源代碼。這是故意的!我們沒有規定將文件從原來的位置刪除。

您還可以一次在多個索引和類型上執行這些操作,類似於搜索API:

UpdateByQueryRequestBuilder updateByQuery = UpdateByQueryAction.INSTANCE.newRequestBuilder(client);
updateByQuery.source("foo", "bar").source().setTypes("a", "b");
BulkByScrollResponse response = updateByQuery.get();

如果您提供了一個路由值,那麼進程將路由值複製到滾動查詢,將進程限制爲與該路由值相匹配的碎片:

UpdateByQueryRequestBuilder updateByQuery = UpdateByQueryAction.INSTANCE.newRequestBuilder(client);
updateByQuery.source().setRouting("cat");
BulkByScrollResponse response = updateByQuery.get();

updateByQuery還可以通過指定這樣一條管道來使用攝取節點:

UpdateByQueryRequestBuilder updateByQuery = UpdateByQueryAction.INSTANCE.newRequestBuilder(client);
updateByQuery.setPipeline("hurray");
BulkByScrollResponse response = updateByQuery.get();

Works with the Task APIedit

您可以使用Task API獲取所有運行更新查詢請求的狀態:

ListTasksResponse tasksList = client.admin().cluster().prepareListTasks()
    .setActions(UpdateByQueryAction.NAME).setDetailed(true).get();
for (TaskInfo info: tasksList.getTasks()) {
    TaskId taskId = info.getTaskId();
    BulkByScrollTask.Status status = (BulkByScrollTask.Status) info.getStatus();
    // do stuff
}

上面顯示的TaskId可以直接查找任務:

GetTaskResponse get = client.admin().cluster().prepareGetTask(taskId).get();

Works with the Cancel Task APIedit

查詢的任何更新都可以使用Task Cancel API取消:

// Cancel all update-by-query requests
client.admin().cluster().prepareCancelTasks().setActions(UpdateByQueryAction.NAME).get().getTasks();
// Cancel a specific update-by-query request
client.admin().cluster().prepareCancelTasks().setTaskId(taskId).get().getTasks();

使用列表任務API來查找taskId的值。

取消請求通常是一個非常快速的過程,但可能需要幾秒鐘。任務狀態API繼續列出任務,直到取消完成爲止。

Rethrottlingedit

在運行的更新中使用re節流API來更改requestspersecond的值:

RethrottleAction.INSTANCE.newRequestBuilder(client)
    .setTaskId(taskId)
    .setRequestsPerSecond(2.0f)
    .get();

使用列表任務API來查找taskId的值。

與updateByQuery API一樣,requestspersecond的值可以是任何正浮動值來設置或者用POSITIVE_INFINITY禁用節流。requests_per_second的值將立即生效。爲了防止滾動超時,requests_per_second在完成當前批處理後,會減慢查詢的速度。



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章