ElasticSearch索引存在不可行/可靠

时间:2014-05-27 07:07:28

标签: java elasticsearch

我正在围绕ElasticSearch的管理客户端编写一个简单的Java包装器。为了测试它,我有一个main方法,首先检查索引是否存在(IndicesExistsRequest),如果是,则删除它(DeleteIndexRequest),并再次创建索引。见下面的代码。然而,我一直得到IndexAlreadyExistsException。

顺便说一句,我正在尝试为您从命令提示符启动的节点获取客户端(只需输入“elastic search”)。我已经在nodeBuilder的流畅界面上尝试了各种方法组合,但我似乎无法获得一个。

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 delete index " + indexName);
    }
    logger.info("Index created");
}

5 个答案:

答案 0 :(得分:26)

您还可以执行如下的同步请求:

boolean exists = client.admin().indices()
    .prepareExists(INDEX_NAME)
    .execute().actionGet().isExists();

答案 1 :(得分:3)

好的,我找到了解决方案。由于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;
}

答案 2 :(得分:3)

如果您想检查实际的索引名称或其任何别名是否可以使用索引,那么skgemini's answer就可以了。

如果您只想通过索引名称进行检查,请按以下步骤进行操作。

public boolean checkIfIndexExists(String index) {

    IndexMetaData indexMetaData = client.admin().cluster()
            .state(Requests.clusterStateRequest())
            .actionGet()
            .getState()
            .getMetaData()
            .index(index);

    return (indexMetaData != null);

}

答案 3 :(得分:2)

使用RestHighLevelClient客户端时,这是我的解决方案;

这是一段代码段::

public boolean checkIfIndexExists(String indexName) throws IOException {
            Response response = client.getLowLevelClient().performRequest("HEAD", "/" + indexName);
            int statusCode = response.getStatusLine().getStatusCode(); 
            return (statusCode != 404);
    }

为别人捐款!

答案 4 :(得分:0)

我有同样的问题,但我不喜欢使用ActionListener的解决方案。 ElasticSearch还提供Future变体(至少在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
    }
}

也许这对其他人也有帮助。干杯!