官方文档地址: Index API
IndexRequest
一个IndexRequest
要求下列参数:
//索引
IndexRequest indexRequest = new IndexRequest("posts");
//请求的文档id
indexRequest.id("1");
String jsonString = "{" +
"\"user\":\"kimchy\"," +
"\"postDate\":\"2013-01-30\"," +
"\"message\":\"trying out Elasticsearch\"" +
"}";
//String提供文档源
indexRequest.source(jsonString, XContentType.JSON);
提供文档源
除了上面显示的String
例子,文档源还可以通过不同的方式提供:
//Map提供文档源,可以自动转换为JSON格式
Map<String, Object> jsonMap = new HashMap<>();
jsonMap.put("user", "kimchy");
jsonMap.put("postDate", new Date());
jsonMap.put("message", "trying out Elasticsearch");
IndexRequest indexRequest = new IndexRequest("posts")
.id("1").source(jsonMap);
//XContentBuilder对象提供文档源,Elasticsearch内置帮助生成JSON内容
XContentBuilder builder = XContentFactory.jsonBuilder();
builder.startObject();
{
builder.field("user", "kimchy");
builder.timeField("postDate", new Date());
builder.field("message", "trying out Elasticsearch");
}
builder.endObject();
IndexRequest indexRequest = new IndexRequest("posts")
.id("1").source(builder);
//Object键值对提供文档源,它被转换为JSON格式
IndexRequest indexRequest = new IndexRequest("posts")
.id("1")
.source("user", "kimchy",
"postDate", new Date(),
"message", "trying out Elasticsearch");
可选参数
可以提供以下参数:
//路由值
indexRequest.routing("routing");
//使用TimeValue作为等待主分片可用的超时时间
indexRequest.timeout(TimeValue.timeValueSeconds(1));
//使用String作为等待主分片可用的超时时间
indexRequest.timeout("1s");
//WriteRequest.RefreshPolicy作为刷新策略
indexRequest.setRefreshPolicy(WriteRequest.RefreshPolicy.WAIT_UNTIL);
//使用String作为刷新策略
indexRequest.setRefreshPolicy("wait_for");
//版本
indexRequest.version(2);
//版本类型
indexRequest.versionType(VersionType.EXTERNAL);
//使用DocWriteRequest.OpType的值设置操作类型
indexRequest.opType(DocWriteRequest.OpType.CREATE);
//使用String设置操作类型:可以是create或index(默认)
indexRequest.opType("create");
//在索引文档之前要执行的摄取管道的名称
indexRequest.setPipeline("pipeline");
同步执行
当以以下方式执行IndexRequest
时,客户端会等待IndexResponse
返回,然后才会继续执行代码:
IndexResponse indexResponse = client.index(indexRequest, RequestOptions.DEFAULT);
同步调用可能会在无法解析高级 REST 客户端中的 REST 响应、请求超时或没有从服务器返回响应等类似情况下会抛出IOException
。
在服务器返回4xx
或5xx
错误代码的情况下,高级客户端尝试解析响应体错误细节,然后抛出一个通用的ElasticsearchException
,并将原始的ResponseException
作为被抑制的异常添加到其中。
异步执行
还可以以异步方式执行IndexRequest
,以便客户端可以直接返回。用户需要通过将请求和侦听器传递给异步 index 方法来指定如何处理响应或潜在的失败:
//要执行的IndexRequest和执行完成时要使用的ActionListener
client.indexAsync(indexRequest, RequestOptions.DEFAULT, listener);
异步方法不会阻塞并会立即返回。如果执行成功,则使用onResponse
方法回调ActionListener
;如果执行失败,则使用onFailure
方法回调ActionListener
。失败场景和预期异常与同步执行情况相同。
index
的标准侦听器如下所示:
listener = new ActionListener<IndexResponse>() {
@Override
public void onResponse(IndexResponse indexResponse) {
//当执行成功完成时调用。
}
@Override
public void onFailure(Exception e) {
//当整个IndexRequest失败时调用。
}
};
IndexResponse
返回的IndexResponse
允许检索关于执行操作的信息,如下所示:
String index = indexResponse.getIndex();
String id = indexResponse.getId();
if (indexResponse.getResult() == DocWriteResponse.Result.CREATED) {
//处理(如果需要)第一次创建文档的情况
} else if (indexResponse.getResult() == DocWriteResponse.Result.UPDATED) {
//处理(如果需要)文档被重写的情况,因为它已经存在
}
ReplicationResponse.ShardInfo shardInfo = indexResponse.getShardInfo();
if (shardInfo.getTotal() != shardInfo.getSuccessful()) {
//处理成功分片的数量小于总分片的情况
}
if (shardInfo.getFailed() > 0) {
for (ReplicationResponse.ShardInfo.Failure failure : shardInfo.getFailures()) {
//处理可能的失败
String reason = failure.reason();
}
}
如果有版本冲突,将抛出一个ElasticsearchException
:
IndexRequest indexRequest = new IndexRequest("posts")
.id("1")
.source("field", "value")
.setIfSeqNo(10L)
.setIfPrimaryTerm(20);
try {
IndexResponse indexResponse = client.index(indexRequest, RequestOptions.DEFAULT);
} catch(ElasticsearchException e) {
if (e.status() == RestStatus.CONFLICT) {
//所引发的异常表明返回了版本冲突错误
}
}
同样的情况也会发生在opType
被设置为create
,并且已经存在一个索引和 id 相同的文档:
IndexRequest indexRequest = new IndexRequest("posts")
.id("1")
.source("field", "value")
.opType(DocWriteRequest.OpType.CREATE);
try {
IndexResponse indexResponse = client.index(indexRequest, RequestOptions.DEFAULT);
} catch(ElasticsearchException e) {
if (e.status() == RestStatus.CONFLICT) {
//所引发的异常表明返回了版本冲突错误
}
}