Giới Thiệu
Elasticsearch là một công cụ tìm kiếm mạnh mẽ và phổ biến, nhưng Java Client API truyền thống yêu cầu phải tương thích về mặt nhị phân với phiên bản của Elasticsearch. Điều này có thể gây khó khăn cho các nhà phát triển khi bảo trì và nâng cấp ứng dụng. Tuy nhiên, từ phiên bản 5.0.0, Elasticsearch đã giới thiệu Java REST Client, cho phép giao tiếp qua giao thức HTTP mà không phụ thuộc vào phiên bản Elasticsearch.
Tại Sao Nên Sử Dụng Java REST Client?
Java REST Client mang đến nhiều lợi ích:
- Tương thích với mọi phiên bản Elasticsearch: Không còn lo về việc không tương thích do phiên bản.
- Dễ dàng tích hợp với các hệ thống khác: Vì sử dụng giao thức HTTP, việc tích hợp trở nên đơn giản và hiệu quả.
- Hỗ trợ xử lý bất đồng bộ (asynchronous): Cho phép thực hiện yêu cầu mà không cần dừng chương trình chờ đợi phản hồi.
Mặc dù có một số nhược điểm như không hỗ trợ fluent APIs hay cách xử lý phản hồi phức tạp, Java REST Client vẫn là một lựa chọn tiềm năng cho nhiều trường hợp sử dụng.
Cài Đặt Thêm Dependency Trong Maven
Để sử dụng Java REST Client, bạn cần cấu hình Apache Maven bằng cách thêm dependency sau vào tệp pom.xml
của ứng dụng:
xml
<dependency>
<groupId>org.elasticsearch.client</groupId>
<artifactId>rest</artifactId>
<version>5.2.0</version>
</dependency>
Cấu Hình Java REST Client Trong Spring Framework
Để cấu hình RestClient, hãy khởi tạo một instance mới sử dụng phương thức .builder()
như sau:
java
@Configuration
public class ElasticsearchClientConfiguration {
@Bean(destroyMethod = "close")
RestClient restClient() {
return RestClient
.builder(new HttpHost("localhost", 9200))
.setRequestConfigCallback(builder ->
builder.setConnectTimeout(1000)
.setSocketTimeout(5000)
)
.build();
}
}
Lưu ý rằng Java REST Client không hỗ trợ thiết lập timeout riêng cho từng yêu cầu, do đó bạn phải cấu hình connect timeout và socket timeout ngay từ khi khởi tạo.
So Sánh Java Client API Và Java REST Client
1. Kiểm Tra Trạng Thái Cluster
Sử dụng Java REST Client để kiểm tra trạng thái cluster:
java
@Test
public void esClusterIsHealthy() throws Exception {
final Response response = client
.performRequest(HttpGet.METHOD_NAME, "_cluster/health", Collections.emptyMap());
final Object json = defaultConfiguration()
.jsonProvider()
.parse(EntityUtils.toString(response.getEntity()));
assertThat(json, hasJsonPath("$.status", equalTo("green")));
}
2. Indexing A Document
Dưới đây là cách xây dựng cấu trúc JSON trong Java:
java
final Map<String, Object> source = new LinkedHashMap<>();
source.put("title", "Elasticsearch: The Definitive Guide");
source.put("categories", new Map[] {
Collections.singletonMap("name", "analytics"),
Collections.singletonMap("name", "search"),
Collections.singletonMap("name", "database store")
});
source.put("publisher", "O’Reilly");
source.put("description", "A comprehensive guide to Elasticsearch.");
source.put("published_date", "2015-02-07");
source.put("isbn", "978-1449358549");
source.put("rating", 4);
Chuyển thành JSON string và gửi yêu cầu để index tài liệu:
java
client.performRequestAsync(
HttpPut.METHOD_NAME,
"catalog/books/978-1449358549",
Collections.emptyMap(),
payload,
new ResponseListener() {
@Override
public void onSuccess(Response response) {
LOG.info("The document has been indexed successfully");
}
@Override
public void onFailure(Exception ex) {
LOG.error("The document has not been indexed", ex);
}
}
);
Tìm Kiếm Dữ Liệu Với Java REST Client
Đối với Java REST Client, bạn sẽ cần cấu trúc truy vấn mà không thể sử dụng fluent APIs như với Java Client API. Một ví dụ tìm kiếm:
java
final Map<String, Object> query = new LinkedHashMap<>();
query.put("size", 10);
query.put("_source", new String[] { "title", "publisher" });
query.put("query", Collections.singletonMap("bool", Collections.singletonMap("must", new Map[] {
Collections.singletonMap("range", Collections.singletonMap("rating", Collections.singletonMap("gte", 4))),
Collections.singletonMap("has_child", Collections.singletonMap("type", "authors")),
Collections.singletonMap("nested", Collections.singletonMap("path", "categories"))
})));
Chuyển đổi truy vấn thành JSON string và gửi yêu cầu tìm kiếm:
java
final HttpEntity payload = new NStringEntity(
JSONObject.toJSONString(query),
ContentType.APPLICATION_JSON
);
final Response response = client.performRequest(
HttpPost.METHOD_NAME,
"catalog/books/_search",
Collections.emptyMap(),
payload
);
final Object json = defaultConfiguration()
.jsonProvider()
.parse(EntityUtils.toString(response.getEntity()));
assertThat(json, hasJsonPath("$.hits.hits[0]._source.title", containsString("Elasticsearch: The Definitive Guide")));
Kết Luận
Ưu Điểm Của Java REST Client
- Tương thích với mọi phiên bản Elasticsearch.
- Dễ dàng tích hợp với các hệ thống khác qua HTTP.
- Hỗ trợ asynchronous cho việc xử lý yêu cầu không đồng bộ.
Nhược Điểm Của Java REST Client
- Không thân thiện và dễ sử dụng như Java Client API.
- Không hỗ trợ Query DSL dạng fluent API.
- Phản hồi được trả lại dưới dạng raw JSON, cần xử lý thêm để trích xuất dữ liệu.
Mặc dù Java Client API vẫn là lựa chọn chính cho nhiều ứng dụng, Java REST Client cung cấp sự linh hoạt và không bị ràng buộc vào phiên bản Elasticsearch, giúp bạn dễ dàng phát triển và mở rộng ứng dụng của mình.