Trong bài hướng dẫn trước chúng ta đã làm quen với Hibernate Search tích hợp với Spring Boot. Hôm nay chúng ta sẽ làm quen với tất cả những kiểu query được Hibernate Search hỗ trợ.
1. Giới thiệu
Nói chính xác hơn chúng ta sẽ tìm hiểu những kiểu query được hỗ trợ bởi Apache Lucence. Mặc dù được ra đời khá lâu nhưng Apache Lucence vẫn là một trong những Database Search mạnh mẽ hỗ trợ giải quyết nhiều dạng bài toán tìm kiếm và sắp xếp cho các Hệ Thống chuyên về quản lý.
Chúng ta sẽ lần lượt tìm hiểu những kiểu query sau:
-
Keyword Query
-
Fuzzy Query
-
Wildcard Query
-
Phrase Query
-
Range Query
2. Hướng dẫn code
Chúng ta đã được hướng dẫn cách setup và tạo Lucence Query trong Spring Controller trong bài viết trước. Bài viết này sẽ không hướng dẫn chi tiết cách tạo các thành phần mà sẽ tập trung vào cách sử dụng và sử dụng vào những yêu cầu như thế nào. Các bạn có thể tìm đọc lại cách setup Hibernate Search ở đây.
2.1 Keyword Query
Đây là kiểu query cơ bản nhất cho bài toán tìm kiếm. Một cách dễ hiểu rằng Hibernate Search sẽ tìm kiếm các cột có chứa nội dung chứa một trong "những từ" tương ứng (matching) với từ khoá cần tìm kiếm. Khi chúng ta index một row dữ liệu mới, các trường có chứa từ khoá @Indexed sẽ được chia nhỏ các từ ra cách nhau bởi khoảng trắng. Khi có request tìm kiếm được gửi xuống, các từ này sẽ được kiểm tra xem có matching không để trả về kết quả. Kết quả trả về sẽ theo thứ tự ưu tiên như sau:
- Có giống hoàn toàn kết quả hay không, kết quả sai khác (thiếu chữ cái trong từ) sẽ nằm sau dữ liệu giống với từ tìm kiếm hoàn toàn.
- Chữ hoa - chữ thường: nếu dữ liệu giống với từ khoá tìm kiếm hoàn toàn sẽ nằm trên, các dữ liệu giống với dữ liệu tìm kiếm nhưng khác chữ hoa - thường. Vd: tìm kiếm chữ "Spring" thì dữ liệu có chữ "Spring" sẽ nằm trên, còn "spring " sẽ nằm bên dưới.
Cách tìm kiếm này đã được sử dụng làm ví dụ trong bài trước.
Query keywordQuery = queryBuilder
.keyword()
.onField(title")
.matching("Spring boot tutorial")
.createQuery();
2.2 Fuzzy Query
FuzzyQuery có cơ chế tìm tương tự như Keyword Query ở trên nhưng cho phép chúng ta định nghĩa thêm "độ nhiễu" khi tìm kiếm, nghĩa là trong quá trình tìm kiếm sẽ chọn ra các từ có độ sai số nhất định. Giá trị "độ nhiễu" chỉ cho phép tối đa là 2, nhỏ nhất là 0. Chúng ta xem ví dụ sau:
Dữ liệu mẫu lấy từ trang doc của Jboss:
Giả sử từ khoá cần tìm kiếm là từ "san francsco" với "độ nhiễu" là 2. Thì những row có cột "name" có chữ "San Francisco" vì so với từ khoá tìm kiếm chúng chỉ sai lệch 1 ký tự (tối đa là 2), còn nếu chúng ta định nghĩa "độ nhiễu" là 0 thì sẽ không có cột nào được trả về, vì yêu cầu query lúc đó là phải giống hoàn toàn chỉ chấp nhận sai khác chữ hoa - thường.
Cú pháp sử dụng:
Query fuzzyQuery = queryBuilder
.keyword()
.fuzzy()
.withEditDistanceUpTo(2)
.withPrefixLength(0)
.onField("productName")
.matching("iPhaen")
.createQuery();
2.3 Wildcard Query
Chúng ta có thể sử dụng các ký tự * và ? để tìm kiếm khi giới hạn được dữ liệu:
- ? đại diện cho 1 ký tự
- * đại diện cho nhiều ký tự
Ví dụ: khi tìm kiếm với từ khoá sau cho cột "name":
franci?co
Kết quả trả về như sau:
Cơ chế này khá đơn giản hơn so với 2 cơ chế ở trên vì ít nhiều chúng ta cũng từng được học và sử dụng tìm kiếm trong Hệ điều hành Windows quen thuộc.
Cú pháp sử dụng, Ví dụ như chúng ta cần tìm các sản phẩm của Apple (bắt đầu bằng chữ 'i'):
Query wildcardQuery = queryBuilder
.keyword()
.wildcard()
.onField("productName")
.matching("i*")
.createQuery();
2.4 Phrase Query:
Được sử dụng trong trường hợp chúng ta cần tìm chính xác một cụm từ vì đôi khi chúng ta biết dữ liệu cần tìm sẽ có chính xác cụm từ đó. Trường hợp này giống như chúng ta sử dụng Google Search:
Các bạn có thể thấy rằng như ở trên chúng ta đang yêu cầu Google chỉ trả về những kết quả có chứa chính xác cụm từ "DTO trong Spring Boot". Chúng ta cũng có thể làm điều tương tự với Phrase Query.
Cú pháp sử dụng:
Query phraseQuery = queryBuilder
.phrase()
.withSlop(1)
.onField("description")
.sentence("4G support")
.createQuery();
2.5 Range Query:
Dùng để tìm kiếm dữ liệu nằm trong một khoảng giá trị, ví dụ những đơn hàng có giá trị từ 1 tỷ đến 2 tỷ. Những kiểu dữ liệu có thể áp dụng được là: numbers, dates, timestamps, và strings:
Query rangeQuery = queryBuilder
.range()
.onField("total")
.from(10000000).to(20000000)
.createQuery();
Chúc các bạn thành công.
AutoCode.VN