[原创] 解决JAVA访问Elasticsearch的问题:org.elasticsearch.client.transport.NoNodeAvailableException: None of the configured nodes are available

本文对应的的Elasticsearch(简写为ES,下同)版本:2.3.5
注:本文写作于多年以前,现在ES已经不提倡使用本文的 TransportClient 来操作ES了,而应使用RestClient。所以本文仅做参考! 2020.08.25

使用Elasticsearch的 JAVA API 来读取其存储的数据,如果遇到这个问题:

org.elasticsearch.client.transport.NoNodeAvailableException: None of the configured nodes are available

此时,需要确认代码里写的一些配置是正确的。下面,就通过一个实例,来说明如何正确地读取ES里的数据。

我们先来看看如何用JAVA代码是怎么写的。

首先,maven依赖如下:

    <dependency>
      <groupId>org.elasticsearch</groupId>
      <artifactId>elasticsearch</artifactId>
      <version>2.3.5</version>
    </dependency>

    <dependency>
      <groupId>com.google.guava</groupId>
      <artifactId>guava</artifactId>
      <version>19.0</version>
    </dependency>

    <dependency>
      <groupId>com.fasterxml.jackson.module</groupId>
      <artifactId>jackson-module-parameter-names</artifactId>
      <version>2.6.6</version>
    </dependency>
    <dependency>
      <groupId>com.fasterxml.jackson.datatype</groupId>
      <artifactId>jackson-datatype-jdk8</artifactId>
      <version>2.6.6</version>
    </dependency>
    <dependency>
      <groupId>com.fasterxml.jackson.datatype</groupId>
      <artifactId>jackson-datatype-jsr310</artifactId>
      <version>2.6.6</version>
    </dependency>
    <dependency>
      <groupId>com.fasterxml.jackson.core</groupId>
      <artifactId>jackson-databind</artifactId>
      <version>2.6.6</version>
    </dependency>

Guava如果不是18.0以上的版本会有问题,Jackson如果是2.8.x或更高版本也会有问题,我急于解决问题,没有记下来具体的错误信息,Google一下便知。
文章来源:http://www.codelast.com/
其次,我们定义一个method,用于初始化ES的client:

  private TransportClient initElasticSearchClient() throws IOException {
    Settings settings = Settings.builder().put("cluster.name""your_es_cluster_name").build();
    TransportClient transportClient = TransportClient.builder().settings(settings).build();
    return transportClient.addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName("192.168.1.25"), 9300));
  }

在这里,我们先要创建一个Settings对象,这个对象包含了访问ES必需的一些属性,例如 cluster.name 这个属性的值,必须要和你ES集群的配置文件 elasticsearch.yml 中的设置一样。
然后,我们使用这个Settings对象,来创建一个client,并且我们需要把ES集群的地址set到这个client里(192.168.1.25),并且端口也要设置对!默认情况下,传输(transport)客户端使用的是9300端口。
文章来源:http://www.codelast.com/
有了这个method,我们就可以用下面的方法来访问ES了:

    Client client = initElasticSearchClient();

    String esIndex = "your_es_data_index";
    SearchResponse searchResponse = client.prepareSearch(esIndex)
      .setTypes("your_es_data_type")
      .setSearchType(SearchType.QUERY_AND_FETCH)
      .setFetchSource(new String[]{"the_field_you_want_to_fetch"}, null)
      .setQuery(QueryBuilders.termsQuery("your_query_key""your_query_value"))
      .execute()
      .actionGet();

    int count = 0;
    for (SearchHit hit : searchResponse.getHits()) {
      Map map = hit.getSource();
      if (count < 3) {
        System.out.println(map);
      } else {
        break;
      }
      ++count;
    }

举个例子,假设ES中的一条JSON数据如下:

{
    "_index": "codelast-2017.02.20", 
    "_type": "Metrics", 
    "_id": "AVpZNqAyzO8IWQrhqbWl", 
    "_score": null, 
    "_source": {
        "a": "123", 
        "b": 456
    }, 
    "fields": {
        "log-time": [
            1487548800000
        ]
    }, 
    "sort": [
        1487548800000
    ]
}

那么代码中的:

  • your_es_data_index 就是“codelast-2017.02.20”
  • your_es_data_type 就是“Metrics”
  • the_field_you_want_to_fetch 即你想让查询返回哪个字段值,这里假设我想得到字段“b”的值,那么这里就填“b”
  • your_query_keyyour_query_value 代表了你的查询条件,例如,在这里,我把它们分别设置成“a”和“123”的话,那么该查询操作就只会查询ES中所有 a == "123" 的数据并返回

文章来源:http://www.codelast.com/
在代码的最后,我们只打印出查询结果中的3条记录,输出结果如下:

{b=78}
{b=99}
{b=25}
这样就完成了一次查询ES的过程。
最后提醒大家注意:默认不做特殊设置的情况下,这样执行查询,ES只返回非常少量的数据(好像是10条,不确定),所以,如果要指定查询ES返回的数据条数,可以在链式设置查询参数的时候,加上一个 setSize(x) 来表示最多返回多少条数据,例如 .setSize(1000) 表示1000条数据。

文章来源:https://www.codelast.com/
➤➤ 版权声明 ➤➤ 
转载需注明出处:codelast.com 
感谢关注我的微信公众号(微信扫一扫):

wechat qrcode of codelast

《[原创] 解决JAVA访问Elasticsearch的问题:org.elasticsearch.client.transport.NoNodeAvailableException: None of the configured nodes are available》有2条评论

发表评论