1. 概述
Quarkus 是一个现代化框架,能轻松愉快地构建高性能应用。本教程将探讨如何将 Quarkus 与 Elasticsearch 集成——这是一个知名的全文搜索引擎和 NoSQL 数据存储系统。
2. 依赖与配置
确保本地已运行 Elasticsearch 实例 后,向 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>
我们添加了两个关键依赖:
quarkus-elasticsearch-rest-client
:提供低级 Elasticsearch REST 客户端quarkus-elasticsearch-java-client
:提供高级 Elasticsearch Java 客户端
✅ 根据实际需求选择合适的客户端
接下来在 application.properties
中配置 Elasticsearch 主机地址:
quarkus.elasticsearch.hosts=localhost:9200
⚠️ 配置完成后,ElasticsearchRestClientProducer
和 ElasticsearchJavaClientProducer
会自动创建必要的 Bean,无需手动干预。
3. Elasticsearch 低级 REST 客户端
使用 低级 REST 客户端 可以完全控制序列化/反序列化过程,并通过 JSON 构建查询。
首先创建索引模型:
public class StoreItem {
private String id;
private String name;
private Long price;
//getters and setters
}
模型包含文档 ID 字段和用于搜索的附加字段。
实现索引方法:
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
- 通过 PUT 请求索引到
/store-items/_doc/{id}
路径
验证索引和搜索的测试方法:
@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);
}
关键流程:
- 索引文档
- 构建 JSON 查询
- 执行搜索请求
- 手动反序列化结果
❌ 需要自行处理所有序列化/反序列化逻辑
4. Elasticsearch Java 客户端
使用 高级 Java 客户端 可以通过 DSL 语法更优雅地构建查询。
索引实现方法:
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
- 通过客户端执行索引
搜索实现方法:
@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);
}
优势对比:
- ✅ 使用 DSL 语法构建查询
- ✅ 自动处理序列化/反序列化
- ✅ 代码更简洁直观
5. 总结
Quarkus 为 Elasticsearch 集成提供了强大支持:
- 简单粗暴:只需添加依赖和简单配置即可快速启动
- 灵活选择:支持低级 REST 客户端和高级 Java 客户端
- 深度定制:可自行定义客户端 Bean 满足特殊需求
⚠️ 实际开发中建议根据场景选择:
- 需要精细控制 JSON 处理 → 低级 REST 客户端
- 追求开发效率 → 高级 Java 客户端
完整源码可在 GitHub 获取。