当前位置:   article > 正文

Elasticsearch教程—Elasticsearch Java API Client [8.6]开发入门(官方原版)

elasticsearch java api client

大家好,我是Doker!

一、开发要求:

  • Java 8 或更高版本。

  • 一个 JSON 对象映射库,允许无缝集成 您的应用程序类与 Elasticsearch API 一起。Java 客户端具有 支持 Jackson 或 Eclipse Yasson 等 JSON-B 库。

二、开发实例

1、在项目的pom.xml中,添加以下存储库定义和依赖项:

  1. <dependencies>
  2. <dependency>
  3. <groupId>co.elastic.clients</groupId>
  4. <artifactId>elasticsearch-java</artifactId>
  5. <version>8.6.2</version>
  6. </dependency>
  7. <dependency>
  8. <groupId>com.fasterxml.jackson.core</groupId>
  9. <artifactId>jackson-databind</artifactId>
  10. <version>2.12.3</version>
  11. </dependency>
  12. </dependencies>

2、连接

Java API客户端由三个主要组件组成:

  • API客户端类。这些为Elasticsearch API提供了强类型的数据结构和方法。由于Elasticsearch API很大,所以它是按功能组(也称为“名称空间”)构建的,每个功能组都有自己的客户端类。Elasticsearch核心功能在ElasticearchClient类中实现。

  • JSON对象映射器。这将应用程序类映射到JSON,并将它们与API客户端无缝集成。

  • 传输层实现。这是所有HTTP请求处理的地方。

此代码段创建并连接以下三个组件:

  1. // Create the low-level client
  2. RestClient restClient = RestClient.builder(
  3. new HttpHost("localhost", 9200)).build();
  4. // Create the transport with a Jackson mapper
  5. ElasticsearchTransport transport = new RestClientTransport(
  6. restClient, new JacksonJsonpMapper());
  7. // And create the API client
  8. ElasticsearchClient client = new ElasticsearchClient(transport);

查询代码:

  1. SearchResponse<Product> search = client.search(s -> s
  2. .index("products")
  3. .query(q -> q
  4. .term(t -> t
  5. .field("name")
  6. .value(v -> v.stringValue("bicycle"))
  7. )),
  8. Product.class);
  9. for (Hit<Product> hit: search.hits().hits()) {
  10. processProduct(hit.source());
  11. }

使用安全连接

在自行安装时,Elasticsearch 将从启用身份验证和 TLS 等安全功能开始。要连接到 Elasticsearch 集群,您需要将 Java API 客户端配置为将 HTTPS 与生成的 CA 证书一起使用,以便成功发出请求。

当你第一次启动Elasticsearch时,你会在Elasticearch的输出中看到一个不同的块,如下图所示(如果有一段时间,你可能需要向上滚动):

  1. -> Elasticsearch security features have been automatically configured!
  2. -> Authentication is enabled and cluster connections are encrypted.
  3. -> Password for the elastic user (reset with `bin/elasticsearch-reset-password -u elastic`):
  4. lhQpLELkjkrawaBoaz0Q
  5. -> HTTP CA certificate SHA-256 fingerprint:
  6. a52dd93511e8c6045e21f16654b77c9ee0f34aea26d9f40320b531c474676228
  7. ...

记下弹性用户密码和HTTP CA指纹,以供下一节使用。在下面的示例中,它们将分别存储在变量password和fingerprint中。

根据上下文,您有两个验证HTTPS连接的选项:使用CA证书本身验证或使用CA证书指纹验证。对于这两种情况,JavaAPI客户端的TransportUtils类提供了方便的方法来轻松创建SSLContext。

使用证书指纹验证 HTTPS

这种验证 HTTPS 连接的方法使用前面记下的证书指纹值。

  1. String fingerprint = "<certificate fingerprint>";
  2. SSLContext sslContext = TransportUtils
  3. .sslContextFromCaFingerprint(fingerprint); (1
  4. BasicCredentialsProvider credsProv = new BasicCredentialsProvider(); (2
  5. credsProv.setCredentials(
  6. AuthScope.ANY, new UsernamePasswordCredentials(login, password)
  7. );
  8. RestClient restClient = RestClient
  9. .builder(new HttpHost(host, port, "https")) (3
  10. .setHttpClientConfigCallback(hc -> hc
  11. .setSSLContext(sslContext) (4
  12. .setDefaultCredentialsProvider(credsProv)
  13. )
  14. .build();
  15. // Create the transport and the API client
  16. ElasticsearchTransport transport = new RestClientTransport(restClient, new JacksonJsonpMapper());
  17. ElasticsearchClient client = new ElasticsearchClient(transport);

(1)使用证书指纹创建SSLContext。

(2)设置身份验证。

(3)不要忘记将协议设置为https!

(4)使用SSL和身份验证配置配置http客户端。

使用CA证书验证HTTPS编辑

生成的根CA证书可以在Elasticsearch配置位置的certs目录中找到。如果您在Docker中运行Elasticsearch,则有其他文档可用于检索CA证书。

一旦应用程序可以使用http_c.crt文件,就可以使用它来设置客户端:

  1. File certFile = new File("/path/to/http_ca.crt");
  2. SSLContext sslContext = TransportUtils
  3. .sslContextFromHttpCaCrt(certFile); (1)
  4. BasicCredentialsProvider credsProv = new BasicCredentialsProvider(); (2)
  5. credsProv.setCredentials(
  6. AuthScope.ANY, new UsernamePasswordCredentials(login, password)
  7. );
  8. RestClient restClient = RestClient
  9. .builder(new HttpHost(host, port, "https")) (3)
  10. .setHttpClientConfigCallback(hc -> hc
  11. .setSSLContext(sslContext) (4)
  12. .setDefaultCredentialsProvider(credsProv)
  13. )
  14. .build();
  15. // Create the transport and the API client
  16. ElasticsearchTransport transport = new RestClientTransport(restClient, new JacksonJsonpMapper());
  17. ElasticsearchClient client = new ElasticsearchClient(transport);

(1)使用http_c.crt文件创建SSLContext。

(2)设置身份验证。

(3)不要忘记将协议设置为https!

(4)使用SSL和身份验证配置配置http客户端。

3、包构和命名空间客户端

Elasticsearch API 很大,并且被组织成功能

Java API客户端遵循这样的结构:功能组称为“命名空间”,每个命名空间都位于co.elastic.clients.elasticsearch的子包中。

每个命名空间客户端都可以从顶级Elasticsearch客户端访问。唯一的例外是“搜索”和“文档”API,它们位于核心子包中,可以在主要的Elasticsearch客户端对象上访问。

下面的代码片段显示了如何使用indexs命名空间客户端创建索引(lambda语法在构建API对象中进行了解释):

  1. ElasticsearchClient client = ...
  2. client.indices().create(c -> c.index("products"));

4、方法命名约定

Java API 客户机中的类包含两种方法和属性:

  • 作为API一部分的方法和财产,例如ElasticsearchClient.search()或SearchResponse.maxScore()。它们是使用标准Java camelCaseNaming约定从Elasticsearch JSON API中各自的名称派生而来的。

  • 方法和财产是构建Java API客户端的框架的一部分,例如Query_kind()。这些方法和财产以下划线作为前缀,既可以避免与API名称发生任何命名冲突,也可以方便地将API与框架区分开来。

5、阻塞和异步客户端

API客户端有两种类型:阻塞和异步。异步客户端上的所有方法都返回标准的CompletableFuture。

根据您的需要,两种口味可以同时使用,共享相同的传输对象:

  1. ElasticsearchTransport transport = ...
  2. // Synchronous blocking client
  3. ElasticsearchClient client = new ElasticsearchClient(transport);
  4. if (client.exists(b -> b.index("products").id("foo")).value()) {
  5. logger.info("product exists");
  6. }
  7. // Asynchronous non-blocking client
  8. ElasticsearchAsyncClient asyncClient =
  9. new ElasticsearchAsyncClient(transport);
  10. asyncClient
  11. .exists(b -> b.index("products").id("foo"))
  12. .whenComplete((response, exception) -> {
  13. if (exception != null) {
  14. logger.error("Failed to index", exception);
  15. } else {
  16. logger.info("Product exists");
  17. }
  18. });

6、构建 API 对象

生成器对象

Java API 客户机中的所有数据类型都是不可变的。对象创建使用2008年在Effective Java中流行的构建器模式。

  1. ElasticsearchClient client = ...
  2. CreateIndexResponse createResponse = client.indices().create(
  3. new CreateIndexRequest.Builder()
  4. .index("my-index")
  5. .aliases("foo",
  6. new Alias.Builder().isWriteIndex(true).build()
  7. )
  8. .build()
  9. );

请注意,生成器在其build()方法被调用后不应被重用。

生成器 lambda 表达式

虽然这很好,但必须实例化生成器类并调用build()方法有点冗长。因此,JavaAPIClient中的每个属性设置器都接受一个lambda表达式,该表达式将新创建的构建器作为参数,并返回一个填充的构建器。上面的代码段也可以写成:

  1. ElasticsearchClient client = ...
  2. CreateIndexResponse createResponse = client.indices()
  3. .create(createIndexBuilder -> createIndexBuilder
  4. .index("my-index")
  5. .aliases("foo", aliasBuilder -> aliasBuilder
  6. .isWriteIndex(true)
  7. )
  8. );

这种方法允许更简洁的代码,并且还避免了导入 类(甚至记住它们的名字),因为类型是从 方法参数签名。

请注意,在上面的示例中,构建器变量仅用于启动链 的财产设置者。因此,这些变量的名称并不重要,并且 可以缩短以提高可读性:

  1. ElasticsearchClient client = ...
  2. CreateIndexResponse createResponse = client.indices()
  3. .create(c -> c
  4. .index("my-index")
  5. .aliases("foo", a -> a
  6. .isWriteIndex(true)
  7. )
  8. );

生成器lambdas对于下面这样的复杂嵌套查询特别有用,这些查询取自interval查询API文档。

本示例还强调了深度嵌套结构中生成器参数的一个有用的命名约定。对于带有单个参数的lambda表达式,Kotlin提供了隐式it参数,Scala允许使用_。这可以在Java中通过使用下划线或单个字母前缀,后跟表示深度级别的数字(即_0、_1或b0、b1等)来近似。这不仅消除了创建一次性变量名的需要,而且还提高了代码的可读性。正确的缩进还可以使查询的结构突出。

  1. ElasticsearchClient client = ...
  2. SearchResponse<SomeApplicationData> results = client
  3. .search(b0 -> b0
  4. .query(b1 -> b1
  5. .intervals(b2 -> b2
  6. .field("my_text")
  7. .allOf(b3 -> b3
  8. .ordered(true)
  9. .intervals(b4 -> b4
  10. .match(b5 -> b5
  11. .query("my favorite food")
  12. .maxGaps(0)
  13. .ordered(true)
  14. )
  15. )
  16. .intervals(b4 -> b4
  17. .anyOf(b5 -> b5
  18. .intervals(b6 -> b6
  19. .match(b7 -> b7
  20. .query("hot water")
  21. )
  22. )
  23. .intervals(b6 -> b6
  24. .match(b7 -> b7
  25. .query("cold porridge")
  26. )
  27. )
  28. )
  29. )
  30. )
  31. )
  32. ),
  33. SomeApplicationData.class
  34. );

7、变量类型

Elasticsearch API有很多变体类型:查询、聚合、字段映射、分析器等等。在这样大的集合中找到正确的类名可能很困难。

JavaAPI客户端构建器使这一点变得简单:变量类型(如Query)的构建器为每个可用实现提供了方法。我们已经在上面的操作中看到了间隔(一种查询)和allOf、match和anyOf(各种间隔)。

这是因为JavaAPI客户端中的变量对象是“标记联合”的实现:它们包含所持有的变量的标识符(或标记)和该变量的值。例如,Query对象可以包含带标记间隔的IntervalsQuery、带标记项的TermQuery等。这种方法允许编写流畅的代码,让IDE完成功能指导您构建和导航复杂的嵌套结构:

变量生成器为每个可用的实现提供setter方法。它们使用与常规财产相同的约定,并接受生成器lambda表达式和实际变量类型的现成对象。下面是一个构建术语查询的示例:

  1. Query query = new Query.Builder()
  2. .term(t -> t (1
  3. .field("name") (2
  4. .value(v -> v.stringValue("foo"))
  5. )
  6. .build(); (3

(1)选择术语变体以构建术语查询。

(2)使用生成器lambda表达式生成术语查询。

(3)构建现在保存一个TermQuery对象的查询。

Elasticsearch教程— Java API Client[8.6] 开发入门2(官方原版)

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/知新_RL/article/detail/334422
推荐阅读
相关标签
  

闽ICP备14008679号