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在完成當前批處理後,會減慢查詢的速度。