1. Khái quát và ví dụ minh họa
1.1. Thiết lập dữ liệu mẫu
Để minh họa, tạo index website với hai tài liệu như sau:
PUT website/_doc/1
{
"title": "Bài học ES cơ bản 01",
"desc": "Bài viết đầu tiên về Elasticsearch",
"level": 1,
"post_date": "2018-10-10",
"post_address": {
"country": "Trung Quốc",
"province": "Quảng Đông",
"city": "Quảng Châu"
}
}
PUT website/_doc/2
{
"title": "Bài học ES cơ bản 02",
"desc": "Bài viết thứ hai về Elasticsearch",
"level": 3,
"post_date": "2018-11-11",
"post_address": {
"country": "Trung Quốc",
"province": "Chiết Giang",
"city": "Hàng Châu"
}
}
1.2. Truy vấn và so sánh hai cách xử lý
Đề bài: Tìm bài viết có level ≥ 2 và post_date = "2018-11-11".
Cách 1: Chỉ dùng query
GET website/_search
{
"query": {
"bool": {
"must": [
{ "term": { "post_date": "2018-11-11" } },
{ "range": { "level": { "gte": 2 } } }
]
}
}
}
Kết quả trả về 1 tài liệu với _score = 2.0.
Cách 2: Kết hợp query và filter
GET website/_search
{
"query": {
"bool": {
"must": [
{ "term": { "post_date": "2018-11-11" } }
],
"filter": [
{ "range": { "level": { "gte": 2 } } }
]
}
}
}
Kết quả trả về 1 tài liệu nhưng _score = 1.0 — score không phản ánh mức độ khớp mà chỉ ghi nhận điều kiện đã được đáp ứng.
2. Các điểm khác biệt chính giữa query và filter
2.1. Xử lý điểm số (scoring)
querytính điểm liên quan (TF/IDF, boost, position...) để hỗ trợ xếp hạng kết quả theo mức độ khớp.filterkhông tính điểm liên quan: tất cả tài liệu phù hợp đều được gán score bằng 1 — tối ưu cho việc type-check hoặc chọn tập con dữ liệu.
2.2. Hiệu năng
filterhiệu quả hơn:- Không tính điểm → không tốn CPU/IO cho sorting.
- Kết quả được cache nội bộ bằng bitset (đặc biệt hiệu quả với dữ liệu thay đổi ít).
querytốn tài nguyên hơn:- Mỗi lần truy vấn đều cần tính lại điểm.
- Không được cache mặc định.
2.3. Nguyên tắc lựa chọn sử dụng
| Mục đích | Tốt nhất dùng |
|---|---|
| Xếp hạng theo mức độ liên quan | query |
| Lọc theo điều kiện cố định (UUID, trạng thái, ngày, phạm vi giá trị...) | filter |