Elasticsearch Bài học 25: Full-text Queries - Match, Match Phrase, và Multi-match
Nếu Term-level queries (ở Bài 24) là những cỗ máy cứng nhắc chỉ biết so khớp 100%, thì Full-text queries chính là linh hồn làm nên sự thông minh của Elasticsearch.
Khi một khách hàng lên Hasaki gõ "kem chống nẵng cetaphil", họ có thể gõ sai chính tả, sai thứ tự từ, hoặc thừa thiếu khoảng trắng. Full-text queries được sinh ra để giải quyết sự "luộm thuộm" đó của ngôn ngữ con người.
Đặc điểm sống còn của Full-text queries: Dữ liệu đầu vào (câu search của user) SẼ BỊ đẩy qua Analyzer trước khi mang đi so khớp với Inverted Index. Quá trình này giúp tính toán Relevance Score (Điểm liên quan) để xếp hạng sản phẩm nào đáng được lên Top 1.
Hãy cùng làm chủ 3 "phép thuật" phổ biến nhất.
1. match Query: Tiêu chuẩn vàng của tìm kiếm
Đây là câu query bạn sẽ dùng nhiều nhất (chiếm 80% use-case).
Cách hoạt động: Khi bạn truyền một câu search vào match, Elasticsearch sẽ băm câu đó thành các từ khóa (tokens). Mặc định, nó sẽ dùng toán tử OR để nối các từ khóa này lại.
Cú pháp:
JSON
GET products/_search
{
"query": {
"match": {
"name": "Sữa rửa mặt Cetaphil"
}
}
}
Phân tích ngầm định: Câu trên sẽ bị Analyzer tách thành: ["sữa", "rửa", "mặt", "cetaphil"]. Elasticsearch sẽ tìm tất cả các Document có chứa ÍT NHẤT 1 TRONG 4 từ trên.
- Hệ quả: Một sản phẩm là
"Sữa tắm bò"cũng sẽ xuất hiện trong kết quả (vì dính chữ "sữa"), nhưng nó sẽ nằm tuốt ở trang cuối vì điểm Score rất thấp. Sản phẩm chứa đủ cả 4 từ sẽ có Score cao nhất và lên Top 1.
Bí kíp tinh chỉnh (Tăng độ khó): Nếu bạn thấy OR trả về quá nhiều kết quả rác, bạn có thể ép nó thành AND, hoặc dùng minimum_should_match để ra lệnh: "Phải khớp ít nhất 70% số từ khóa thì mới được hiển thị".
JSON
"match": {
"name": {
"query": "Sữa rửa mặt Cetaphil",
"operator": "and", // Ép phải có đủ 4 chữ
"minimum_should_match": "75%" // Hoặc khớp 3/4 chữ là chấp nhận
}
}
2. match_phrase Query: Tìm kiếm theo cụm từ (Khớp thứ tự)
Sẽ có lúc khách hàng muốn tìm chính xác một cụm từ đi liền nhau. Ví dụ: "áo thun nam". Nếu dùng match thường, một sản phẩm mang tên "Áo khoác nữ màu thun nam tính" cũng bị lọt vào vì có chứa các từ rời rạc.
Để ép các chữ phải đứng cạnh nhau và đúng thứ tự, ta dùng match_phrase.
Cú pháp:
JSON
GET products/_search
{
"query": {
"match_phrase": {
"name": "áo thun nam"
}
}
}
-
"Áo thun nam Hàn Quốc"-> Trúng (Đúng thứ tự, đứng cạnh nhau). -
"Áo thun ngắn tay cho nam"-> Trượt (Vì có chữ "ngắn tay cho" xen vào giữa).
Vũ khí làm mềm match_phrase (Tham số slop): Đôi khi match_phrase quá khắt khe. Khách gõ "áo thun nam", nhưng kho của bạn lưu là "áo thun cotton nam". Bằng cách thêm tham số slop, bạn cho phép các từ khóa được phép "cách nhau" bao nhiêu khoảng trống.
JSON
"match_phrase": {
"name": {
"query": "áo thun nam",
"slop": 1 // Cho phép 1 từ khác chui vào giữa
}
}
3. multi_match Query: Tung lưới bủa vây nhiều trường cùng lúc
Trên trang chủ E-commerce, ô tìm kiếm thường chỉ có một. Nhưng khách hàng có thể nhập tên sản phẩm, tên thương hiệu, hoặc danh mục vào đó. Bạn không thể chỉ search mỗi trường name.
multi_match cho phép bạn ném một từ khóa vào nhiều trường (fields) khác nhau cùng một lúc.
Cú pháp:
JSON
GET products/_search
{
"query": {
"multi_match": {
"query": "Sữa rửa mặt Cetaphil",
"fields": ["name", "brand", "category", "description"]
}
}
}
Bí kíp "Boosting" (Nhân trọng số): Trong ví dụ trên, nếu từ "Cetaphil" xuất hiện ở tên sản phẩm (name), nó phải có giá trị (điểm số) cao hơn nhiều so với việc nó vô tình xuất hiện ở phần mô tả (description). Bạn có thể gắn trọng số (Boost) trực tiếp vào trường bằng ký hiệu mũ ^.
JSON
"fields": [
"name^3", // Điểm của trường name nhân 3
"brand^2", // Điểm của trường brand nhân 2
"category", // Nhân 1 (Mặc định)
"description" // Nhân 1
]
4. Tóm lược chiến thuật áp dụng
Khi thiết kế hệ thống tìm kiếm (Search Engine), các Backend Engineer thường không dùng đơn lẻ 1 câu lệnh, mà kết hợp chúng trong một khối bool (Bài 23) theo nguyên lý Phễu (Funnel):
-
Tầng 1 (Chính xác tuyệt đối - Top 1): Dùng
match_phraseđể ưu tiên đẩy lên đầu những sản phẩm khớp chính xác cả cụm từ khách gõ. -
Tầng 2 (Bủa lưới trọng số - Top 2 -> 10): Dùng
multi_matchvớioperator: "and"kết hợpboostingđể tìm những sản phẩm có đủ các từ khóa, nằm rải rác ở Name và Brand. -
Tầng 3 (Vét máng - Trang cuối): Dùng
matchvớioperator: "or"để phòng trường hợp kho không có đồ khách muốn, nhưng vẫn hiện ra vài món "tương tự" (chỉ trùng 1 chữ) để khách khỏi thấy màn hình trắng trơn.
Tuy nhiên, dù bạn có thiết lập match hay match_phrase hay cỡ nào, nếu user gọi đúng câu query nhưng lại muốn lọc thêm dữ liệu cứng (Giá tiền, Hãng, Ngày tháng), chúng ta lại phải sử dụng kết hợp với Compound query. Hãy cùng đi sâu vào khối bool thần thánh ở bài sau.
All Rights Reserved