Java ElasticSearch 索引存在不工作/可靠

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/23883110/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-14 08:50:12  来源:igfitidea点击:

ElasticSearch index exists not working / reliable

javaelasticsearch

提问by user3663845

I am writing a simple Java wrapper around ElasticSearch's admin client. To test it I have a main method that first checks if an index exists (IndicesExistsRequest), if so deletes it (DeleteIndexRequest), and creates the index again. See code below. Yet I consistently get an IndexAlreadyExistsException.

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

By the way I am trying to get a client for the node that you start from the command prompt (by simply typing "elastic search"). I have tried every combination of methods on nodeBuilder's fluent interface, but I can't seem to get one.

顺便说一下,我试图为您从命令提示符启动的节点获取客户端(只需键入“弹性搜索”)。我已经尝试了 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");
}

采纳答案by user3663845

OK, I figured out a solution. Since the java client's calls are done asynchronously you have to use the variant which takes an action listener. The solution still gets a bit contrived though:

好的,我想出了一个解决方案。由于 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;
}

回答by skgemini

You can also execute a synchronous request like this:

您还可以执行这样的同步请求:

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

回答by npe

The skgemini's answeris ok if you want to check if index is available by the actual index nameor any of its aliases.

skgemini的答案,如果你想检查指标可通过实际是确定指数名称或其任何的别名

If you however want to check only by the index name, here is how.

但是,如果您只想通过索引名称进行检查,则方法如下。

public boolean checkIfIndexExists(String index) {

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

    return (indexMetaData != null);

}

回答by user3227576

I had the same issue but i didn't like the solution which uses an ActionListener. ElasticSearch also offers a Future variant (at least at version 6.1.0).

我有同样的问题,但我不喜欢使用 ActionListener 的解决方案。ElasticSearch 还提供了 Future 变体(至少在 6.1.0 版本中)。

Here a code-snippet:

这是一个代码片段:

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
    }
}

May be this helps someone else too. Cheers!

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

回答by Maodo Diop

Here is my solution when using RestHighLevelClient client;

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

Here a code-snippet: :

这是一个代码片段::

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

A contribution for someone else !

对别人的贡献!