51工具盒子

依楼听风雨
笑看云卷云舒,淡观潮起潮落

Quarkus 整合 Elasticsearch

1、概览 {#1概览}

Quarkus 是一个现代框架,它能让你轻松高效地地构建高性能应用。

本文将带你了解如何在 Quarkus 中整合 Elasticsearch,一个著名的全文搜索引擎和 NoSQL 数据库。

2、依赖和配置 {#2依赖和配置}

首先,你需要在本地主机上运行 Elasticsearch 实例(推荐用 Docker 的方式)。

然后,在 Quarkus 应用中添加依赖:

<dependency>
    <groupId>io.quarkus</groupId>
    <artifactId>quarkus-elasticsearch-rest-client</artifactId>
    <version>${quarkus.version}</version>
</dependency>
<dependency>
    <groupId>io.quarkus</groupId>
    <artifactId>quarkus-elasticsearch-java-client</artifactId>
    <version>${quarkus.version}</version>
</dependency>

在我们的应用中,可以根据需要选择使用合适的客户端。

接下来,将 Elasticsearch HOST 添加到 application.properties 文件中:

quarkus.elasticsearch.hosts=localhost:9200

现在,我们可以开始在 Quarkus 应用中使用 Elasticsearch 了。ElasticsearchRestClientProducerElasticsearchJavaClientProducer 会自动创建所有必要的 Bean。

3、Elasticsearch 低级 REST 客户端 {#3elasticsearch-低级-rest-客户端}

我们可以使用 Elasticsearch 低级 REST 客户端 将应用与 Elasticsearch 集成。这使得我们可以完全控制序列化和反序列化过程,并允许我们使用 JSON 构建 Elasticsearch 的查询。

创建一个要在应用中索引的文档模型:

public class StoreItem {
    private String id;
    private String name;
    private Long price;
    // Getter / Setter 方法省略
}

在这个文档模型中,有一个id 字段。以及其他的一些用于检索的字段。

现在,实现索引 StoreItem 的方法:

private void indexUsingRestClient() throws IOException, InterruptedException {
    iosPhone = new StoreItem();
    iosPhone.setId(UUID.randomUUID().toString());
    iosPhone.setPrice(1000L);
    iosPhone.setName("IOS smartphone");

    Request restRequest = new Request(
      "PUT",
      "/store-items/_doc/" + iosPhone.getId());
    restRequest.setJsonEntity(JsonObject.mapFrom(iosPhone).toString());
    restClient.performRequest(restRequest);
}

如上,创建了一个具有随机 id 和特定名称的 StoreItem。然后,向 /store-items/_doc/{id} 路径执行一个 PUT 请求,以索引我们的文档。现在,我们要创建一个方法来验证我们的文档是否被成功地索引,并根据不同字段进行搜索:

@Test
void givenRestClient_whenSearchInStoreItemsByName_thenExpectedDocumentsFound() throws Exception {
    indexUsingRestClient();

    Request request = new Request(
      "GET",
      "/store-items/_search");

    JsonObject termJson = new JsonObject().put("name", "IOS smartphone");
    JsonObject matchJson = new JsonObject().put("match", termJson);
    JsonObject queryJson = new JsonObject().put("query", matchJson);
    request.setJsonEntity(queryJson.encode());

    Response response = restClient.performRequest(request);
    String responseBody = EntityUtils.toString(response.getEntity());

    JsonObject json = new JsonObject(responseBody);
    JsonArray hits = json.getJsonObject("hits").getJsonArray("hits");
    List<StoreItem> results = new ArrayList<>(hits.size());

    for (int i = 0; i < hits.size(); i++) {
        JsonObject hit = hits.getJsonObject(i);
        StoreItem fruit = hit.getJsonObject("_source").mapTo(StoreItem.class);
        results.add(fruit);
    }

    assertThat(results)
      .hasSize(1)
      .containsExactlyInAnyOrder(iosPhone);
}

我们使用 indexUsingRestClient() 方法索引了 StoreItem。然后,创建 JSON 查询并执行搜索请求。最后对每个搜索结果进行反序列化,并验证其中是否包含 StoreItem

这样,我们就在 Quarkus 应用中使用底层 REST 客户端实现了与 Elasticsearch 的基本集成。如你所见,我们需要自己处理所有序列化和反序列化过程。

4、Elasticsearch Java 客户端 {#4elasticsearch-java-客户端}

Elasticsearch Java 客户端是更高级别的客户端。我们可以使用它的 DSL 语法更优雅地创建 Elasticsearch 查询。

使用该客户端创建一个方法来索引 StoreItem

private void indexUsingElasticsearchClient() throws IOException, InterruptedException {
    androidPhone = new StoreItem();
    androidPhone.setId(UUID.randomUUID().toString());
    androidPhone.setPrice(500L);
    androidPhone.setName("Android smartphone");

    IndexRequest<StoreItem> request = IndexRequest.of(
      b -> b.index("store-items")
        .id(androidPhone.getId())
        .document(androidPhone));

    elasticsearchClient.index(request);
}

我们创建了另一个 StoreItem 文档,然后构建了 IndexRequest。最后,调用 Elasticsearch Java 客户端的 index() 方法来执行请求。

现在,检索已保存的项目:

@Test
void givenElasticsearchClient_whenSearchInStoreItemsByName_thenExpectedDocumentsFound() throws Exception {
    indexUsingElasticsearchClient();
    Query query = QueryBuilders.match()
      .field("name")
      .query(FieldValue.of("Android smartphone"))
      .build()
      ._toQuery();

    SearchRequest request = SearchRequest.of(
      b -> b.index("store-items")
        .query(query)
    );
    SearchResponse<StoreItem> searchResponse = elasticsearchClient
      .search(request, StoreItem.class);

    HitsMetadata<StoreItem> hits = searchResponse.hits();
    List<StoreItem> results = hits.hits().stream()
      .map(Hit::source)
      .collect(Collectors.toList());

    assertThat(results)
      .hasSize(1)
      .containsExactlyInAnyOrder(androidPhone);
}

我们使用 indexUsingElasticsearchClient() 方法为新文档编制了索引。然后,创建了 SearchRequest,并用 Elasticsearch Java 客户端执行了该请求,并将所有搜索结果收集到 StoreItem 集合中。

我们使用 DSL 语法创建查询,因此不必操心序列化和反序列化问题。

5、总结 {#5总结}

如你所见,在 Quarkus 中整合 Elasticsearch 只需添加相关依赖和几行配置即可。你可以选择使用底层的 REST 客户端或高级的 Java 客户端。如果你想要更多控制权,可以自己定义客户端 Bean。


Ref:https://www.baeldung.com/elasticsearch-quarkus-connect

赞(0)
未经允许不得转载:工具盒子 » Quarkus 整合 Elasticsearch