Giới Thiệu về Hibernate Search và Elasticsearch
Trong thế giới phát triển phần mềm, Hibernate không còn là cái tên xa lạ với hầu hết các lập trình viên. Tuy nhiên, không phải ai cũng biết rằng dưới sự phát triển của Hibernate, có một công cụ mạnh mẽ mang tên Hibernate Search.
Hibernate Search cho phép lập chỉ mục (indexing) tự động cho các đối tượng và hỗ trợ khả năng tìm kiếm toàn văn (full-text search) cùng tìm kiếm theo vị trí địa lý (geolocation search) với hiệu suất cao. Ban đầu, dự án này chỉ là một lớp kết nối giữa Hibernate và Apache Lucene, nhưng từ phiên bản Hibernate Search 5.7.0, nó hỗ trợ tích hợp với Elasticsearch, mở ra nhiều cơ hội cho các ứng dụng Java.
Lợi Ích Của Việc Tích Hợp Elasticsearch với Hibernate Search
Việc tích hợp Elasticsearch với Hibernate giúp bạn cải thiện khả năng tìm kiếm trên ứng dụng mà không cần thay đổi lớn trong mã nguồn. Chỉ với một vài cấu hình đơn giản, bạn có thể khai thác sức mạnh của công cụ tìm kiếm mạnh mẽ này, từ đó cải thiện trải nghiệm người dùng.
Cách Hibernate Search Hoạt Động Với Elasticsearch
Dưới đây là một mô hình dữ liệu cho catalog của chúng ta, được thể hiện qua các JPA entities và sử dụng các Hibernate Search annotations để tích hợp với Elasticsearch.
Ví Dụ về Entity Book
java
@Entity
@Table(name = "BOOKS")
@Indexed(index = "catalog")
public class Book {
@Id
@Field(name = "isbn", analyze = Analyze.NO)
private String id;
@Field
@Column(name = "TITLE", nullable = false)
private String title;
@IndexedEmbedded(depth = 1)
@ElementCollection
private Set<Category> categories = new HashSet<>();
@Field(analyze = Analyze.NO)
@Column(name = "PUBLISHER", nullable = false)
private String publisher;
@Field
@Column(name = "DESCRIPTION", nullable = false, length = 4096)
private String description;
@Field(name = "published_date", analyze = Analyze.NO)
@Column(name = "PUBLISHED_DATE", nullable = false)
@DateBridge(resolution = Resolution.DAY)
private LocalDate publishedDate;
@NumericField
@Field(name = "rating")
@Column(name = "RATING", nullable = false)
private int rating;
@IndexedEmbedded
@ManyToMany
private Set<Author> authors = new HashSet<>();
}
Như bạn có thể thấy, đây là một JPA entity thường thấy, kèm theo một số Hibernate Search annotations như @Field
, @DateBridge
, @IndexedEmbedded
, giúp lập chỉ mục dữ liệu lên Elasticsearch một cách tự động.
Hướng Dẫn Tích Hợp Hibernate Search Với Spring Boot
Việc cấu hình Hibernate Search để sử dụng Elasticsearch làm backend trên Spring Boot vô cùng đơn giản. Chỉ cần thêm một vài dòng vào tệp application.yml
:
yaml
spring:
jpa:
properties:
hibernate.search.default.indexmanager: elasticsearch
hibernate.search.default.elasticsearch.host: https://localhost:9200
Mỗi khi bạn tạo, cập nhật hoặc xóa một thực thể Book hoặc Author, Hibernate Search sẽ tự động đồng bộ hóa với Elasticsearch, hoàn toàn trong suốt với ứng dụng.
Thực Hiện Tìm Kiếm Với Hibernate Search
Hibernate Search cung cấp một lớp Query DSL dựa trên Apache Lucene queries, đồng thời cho phép bạn kết hợp một số tính năng gốc của Elasticsearch.
Chẳng hạn, bạn cần tìm tất cả các books thuộc danh mục "analytics" và có tác giả là "Tong":
java
@Autowired private EntityManager entityManager;
final FullTextEntityManager fullTextEntityManager = Search.getFullTextEntityManager(entityManager);
final QueryBuilder qb = fullTextEntityManager.getSearchFactory()
.buildQueryBuilder()
.forEntity(Book.class)
.get();
final FullTextQuery query = fullTextEntityManager.createFullTextQuery(
qb.bool()
.must(qb.keyword().onField("categories.name").matching("analytics").createQuery())
.must(qb.keyword().onField("authors.last_name").matching("Tong").createQuery())
.createQuery(),
Book.class
);
final List<Book> books = query.getResultList();
Cú pháp này rất gần gũi với Query DSL của Elasticsearch, vì vậy nó sẽ rất dễ dàng nếu bạn đã quen với Elasticsearch trước đó.
Một Số Hạn Chế Cần Lưu Ý
Dù Hibernate Search mang lại khả năng tích hợp nhanh chóng giữa Hibernate và Elasticsearch, nhưng vẫn còn một số hạn chế đáng lưu ý:
- Chỉ hỗ trợ Elasticsearch 2.4.4 tính đến thời điểm bài viết này, chưa tương thích với các phiên bản 5.x hoặc cao hơn.
- Bộ API hạn chế, đặc biệt là đối với Query DSL, chưa hỗ trợ đầy đủ tất cả tính năng của Elasticsearch.
Tuy nhiên, nếu bạn đang sử dụng Hibernate và muốn dễ dàng thêm full-text search vào ứng dụng, Hibernate Search vẫn là một lựa chọn rất hấp dẫn. 🚀