Java ElasticSearch索引存在不工作/不可靠
我正在围绕ElasticSearch的管理客户端编写一个简单的Java包装器。为了测试它,我有一个main方法,首先检查索引是否存在(indicexistrequest),如果存在,则删除它(DeleteIndexRequest),然后再次创建索引。请参阅下面的代码。但我一直有一种指数型的超前性感觉 顺便说一句,我试图为从命令提示符启动的节点获取客户端(只需键入“弹性搜索”)。我在nodeBuilder的fluent界面上尝试了各种方法的组合,但似乎都没有Java ElasticSearch索引存在不工作/不可靠,java,
elasticsearch,Java,
elasticsearch,我正在围绕ElasticSearch的管理客户端编写一个简单的Java包装器。为了测试它,我有一个main方法,首先检查索引是否存在(indicexistrequest),如果存在,则删除它(DeleteIndexRequest),然后再次创建索引。请参阅下面的代码。但我一直有一种指数型的超前性感觉 顺便说一句,我试图为从命令提示符启动的节点获取客户端(只需键入“弹性搜索”)。我在nodeBuilder的fluent界面上尝试了各种方法的组合,但似乎都没有 public static void
public static void main(String[] args) {
ElasticSearchJavaClient esjc = new ElasticSearchJavaClient("nda");
if (esjc.indexExists()) {
esjc.deleteIndex();
}
esjc.createIndex();
URL url = SchemaCreator.class.getResource("/elasticsearch/specimen.type.json");
String mappings = FileUtil.getContents(url);
esjc.createType("specimen", mappings);
}
final Client esClient;
final IndicesAdminClient adminClient;
final String indexName;
public ElasticSearchJavaClient(String indexName) {
this.indexName = indexName;
esClient = nodeBuilder().clusterName("elasticsearch").client(true).node().client();
adminClient = esClient.admin().indices();
}
public boolean deleteIndex() {
logger.info("Deleting index " + indexName);
DeleteIndexRequest request = new DeleteIndexRequest(indexName);
try {
DeleteIndexResponse response = adminClient.delete(request).actionGet();
if (!response.isAcknowledged()) {
throw new Exception("Failed to delete index " + indexName);
}
logger.info("Index deleted");
return true;
} catch (IndexMissingException e) {
logger.info("No such index: " + indexName);
return false;
}
}
public boolean indexExists() {
logger.info(String.format("Verifying existence of index \"%s\"", indexName));
IndicesExistsRequest request = new IndicesExistsRequest(indexName);
IndicesExistsResponse response = adminClient.exists(request).actionGet();
if (response.isExists()) {
logger.info("Index exists");
return true;
}
logger.info("No such index");
return false;
}
public void createIndex() {
logger.info("Creating index " + indexName);
CreateIndexRequest request = new CreateIndexRequest(indexName);
IndicesAdminClient iac = esClient.admin().indices();
CreateIndexResponse response = iac.create(request).actionGet();
if (!response.isAcknowledged()) {
throw new Exception("Failed to create index " + indexName);
}
logger.info("Index created");
}
好的,我想出了一个解决办法。由于java客户机的调用是异步完成的,因此必须使用带有操作侦听器的变量。不过,解决方案还是有点做作:
// Inner class because it's just used to be thrown out of
// the action listener implementation to signal that the
// index exists
private class ExistsException extends RuntimeException {
}
public boolean exists() {
logger.info(String.format("Verifying existence of index \"%s\"", indexName));
IndicesExistsRequest request = new IndicesExistsRequest(indexName);
try {
adminClient.exists(request, new ActionListener<IndicesExistsResponse>() {
public void onResponse(IndicesExistsResponse response) {
if (response.isExists()) {
throw new ExistsException();
}
}
public void onFailure(Throwable e) {
ExceptionUtil.smash(e);
}
});
}
catch (ExistsException e) {
return true;
}
return false;
}
//内部类,因为它只是用来从
//操作侦听器实现,以指示
//索引存在
私有类ExistSexException扩展了RuntimeException{
}
公共布尔存在(){
logger.info(String.format(“验证索引\%s\”和indexName的存在”);
IndicateSistsRequest请求=新IndicateSistsRequest(indexName);
试一试{
存在(请求,新ActionListener(){
公共无效响应(表示存在响应响应){
if(response.isExists()){
抛出新的ExistsException();
}
}
失败时的公共无效(可丢弃的e){
例外直到粉碎(e);
}
});
}
捕获(存在异常e){
返回true;
}
返回false;
}
您还可以执行如下同步请求:
boolean exists = client.admin().indices()
.prepareExists(INDEX_NAME)
.execute().actionGet().isExists();
如果要通过实际索引名或其任何别名检查索引是否可用,则可以
但是,如果您只想通过索引名进行检查,下面是如何进行检查的
public boolean checkIfIndexExists(String index) {
IndexMetaData indexMetaData = client.admin().cluster()
.state(Requests.clusterStateRequest())
.actionGet()
.getState()
.getMetaData()
.index(index);
return (indexMetaData != null);
}
我也有同样的问题,但我不喜欢使用ActionListener的解决方案。ElasticSearch还提供了未来的变体(至少版本6.1.0) 下面是一段代码片段:
public boolean doesIndexExists(String indexName, TransportClient client) {
IndicesExistsRequest request = new IndicesExistsRequest(indexName);
ActionFuture<IndicesExistsResponse> future = client.admin().indices().exists(request);
try {
IndicesExistsResponse response = future.get();
boolean result = response.isExists();
logger.info("Existence of index '" + indexName + "' result is " + result);
return result;
} catch (InterruptedException | ExecutionException e) {
logger.error("Exception at waiting for IndicesExistsResponse", e);
return false;//do some clever exception handling
}
}
public boolean doesIndexists(字符串索引名,TransportClient){
IndicateSistsRequest请求=新IndicateSistsRequest(indexName);
ActionFuture=client.admin().index().存在(请求);
试一试{
IndicateSistsResponse response=future.get();
布尔结果=response.isExists();
logger.info(“存在索引“+”索引名“+”结果为“+结果”);
返回结果;
}捕获(中断异常|执行异常e){
logger.错误(“等待指示存在响应时异常”,e);
return false;//执行一些巧妙的异常处理
}
}
也许这对其他人也有帮助。干杯 这是我使用RestHighLevelClient时的解决方案 下面是一段代码片段:
public boolean checkIfIndexExists(String indexName) throws IOException {
Response response = client.getLowLevelClient().performRequest("HEAD", "/" + indexName);
int statusCode = response.getStatusLine().getStatusCode();
return (statusCode != 404);
}
对别人的贡献 请注意,如果
INDEX\u NAME
是现有索引的别名,则此调用也将返回true
。对我来说,这应该是最好的答案,因为client.admin().INDEX().prepareExists(“indexName”).execute().actionGet().isExists()代码>始终返回false
,尽管存在indexName