Update API
Update Request
UpdateRequest需要以下参数:
UpdateRequest request = new UpdateRequest(
"posts",
"doc",
"1");
Update API允许通过使用脚本或传递部分文档来更新现有文档。
使用脚本进行更新
该脚本可以作为内联脚本提供:
Map<String, Object> parameters = singletonMap("count", 4); //Map对象作为脚本参数
Script inline = new Script(ScriptType.INLINE, "painless",
"ctx._source.field += params.count", parameters);
request.script(inline); //将脚本设置为更新请求
作为一个存储脚本
Script stored = new Script(
ScriptType.STORED, null, "increment-field", parameters);
request.script(stored);
使用脚本进行更新未能实现?
部分文档进行更新
当对部分文档使用更新时,该部分文档将与现有文档合并。
UpdateRequest request = new UpdateRequest("posts", "doc", "1");
String jsonString = "{" +
"\"updated\":\"2017-01-01\"," +
"\"reason\":\"daily update\"" +
"}";
request.doc(jsonString, XContentType.JSON);
Map<String, Object> jsonMap = new HashMap<>();
jsonMap.put("updated", new Date());
jsonMap.put("reason", "daily update");
UpdateRequest request = new UpdateRequest("posts", "doc", "1")
.doc(jsonMap);
XContentBuilder builder = XContentFactory.jsonBuilder();
builder.startObject();
{
builder.timeField("updated", new Date());
builder.field("reason", "daily update");
}
builder.endObject();
UpdateRequest request = new UpdateRequest("posts", "doc", "1")
.doc(builder);
UpdateRequest request = new UpdateRequest("posts", "doc", "1")
.doc("updated", new Date(),
"reason", "daily update");
Upserts
如果文档还不存在,可以使用upsert方法定义一些内容作为新文档插入:
与部分文档更新类似,upsert文档的内容可以使用接受字符串、Map、XContentBuilder或对象键对的方法来定义。
String jsonString = "{\"created\":\"2017-01-01\"}";
request.upsert(jsonString, XContentType.JSON); //以字符串形式提供的Upsert文档源
可以选择提供以下参数
如果文档在更更新操作的时候,被其他的get或者另一个操作更改,那么要重试更新操作多少次
request.retryOnConflict(3);
启用源检索,默认情况下禁用
request.fetchSource(true);
禁用noop检测
request.detectNoop(false);
表示无论文档是否存在,脚本都必须运行,即如果文档不存在,脚本将负责创建文档。
request.scriptedUpsert(true);
指示如果部分文档尚不存在,则必须将其用作upsert文档。
request.docAsUpsert(true);
同步执行
当以以下方式执行UpdateRequest时,客户端等待UpdateResponse返回,然后继续执行代码:
UpdateResponse updateResponse = client.update(
request, RequestOptions.DEFAULT);
同步调用可能会抛出IOException,以防在高级REST客户机中解析REST响应失败、请求超时或类似情况下没有响应从服务器返回。
异步执行
client.updateAsync(request, RequestOptions.DEFAULT, listener);
Update Response
返回的UpdateResponse允许检索有关执行操作的信息如下
String index = updateResponse.getIndex();
String type = updateResponse.getType();
String id = updateResponse.getId();
long version = updateResponse.getVersion();
if (updateResponse.getResult() == DocWriteResponse.Result.CREATED) {
//处理第一次创建文档的情况(upsert)
} else if (updateResponse.getResult() == DocWriteResponse.Result.UPDATED) {
//处理文档更新的情况
} else if (updateResponse.getResult() == DocWriteResponse.Result.DELETED) {
//处理删除文档的情况
} else if (updateResponse.getResult() == DocWriteResponse.Result.NOOP) {
//处理文档不受更新影响的情况,即在文档上不执行任何操作(noop)
}
当通过fetchSource方法在UpdateRequest中启用源检索时,响应包含更新文档的源:
GetResult result = updateResponse.getGetResult(); //以GetResult的形式检索更新后的文档
if (result.isExists()) {
String sourceAsString = result.sourceAsString();
Map<String, Object> sourceAsMap = result.sourceAsMap();
byte[] sourceAsBytes = result.source();
} else {
//处理响应中不存在文档源的场景(默认情况下是这样)
}
可以检查分片故障:
ReplicationResponse.ShardInfo shardInfo = updateResponse.getShardInfo();
if (shardInfo.getTotal() != shardInfo.getSuccessful()) {
}
if (shardInfo.getFailed() > 0) {
for (ReplicationResponse.ShardInfo.Failure failure :
shardInfo.getFailures()) {
String reason = failure.reason();
}
}
UpdateRequest对不存在的文档执行时,响应有404状态代码,抛出ElasticsearchException,需要处理如下:
UpdateRequest request = new UpdateRequest("posts", "type", "does_not_exist")
.doc("field", "value");
try {
UpdateResponse updateResponse = client.update(
request, RequestOptions.DEFAULT);
} catch (ElasticsearchException e) {
if (e.status() == RestStatus.NOT_FOUND) {
//处理因文档不存在而引发的异常
}else if (e.status() == RestStatus.CONFLICT) {
//引发的异常表明返回了版本冲突错误
}
}
如果存在版本冲突,将抛出ElasticsearchException: