1. Cấu hình bộ lọc payload (payload filtering) cho metadata
Bước đầu tiên để tối ưu tìm kiếm là khai báo chính xác cấu trúc metadata (payload) khi tạo Collection. Qdrant cần biết loại dữ liệu (integer, string, float) của mỗi trường để xây dựng chỉ mục tìm kiếm chính xác.
Chúng ta sẽ tạo một Collection mới có tên hybrid_docs với các trường payload mô tả văn bản, bao gồm title, category, và author. Việc khai báo rõ ràng này là tiền đề bắt buộc cho bước lọc sau này.
Thực thi lệnh API để tạo Collection với cấu hình payload:
curl --location "http://localhost:6333/collections/hybrid_docs" \
--header "Content-Type: application/json" \
--data '{
"vectors": {
"size": 1536,
"distance": "Cosine"
},
"sparse_vectors": {
"index": {
"on_disk": false
}
},
"sparse_vectors_config": {
"keyword": {
"index": {
"on_disk": false
}
}
},
"payload_schema": {
"title": { "data_type": "text" },
"category": { "data_type": "text" },
"author": { "data_type": "text" },
"year": { "data_type": "integer" }
}
}'
Kết quả mong đợi: Trả về JSON chứa "status": "ok", xác nhận Collection đã được tạo với các trường payload đã được định nghĩa sẵn.
2. Tích hợp chỉ mục đảo (inverted index) cho tìm kiếm văn bản
Để thực hiện tìm kiếm theo từ khóa (keyword search) hiệu quả, ta cần kích hoạt Inverted Index cho các trường text trong payload. Mặc định, Qdrant có thể không index các trường text nếu không cấu hình, dẫn đến việc tìm kiếm chậm hoặc không khả thi với dữ liệu lớn.
Chúng ta sẽ cập nhật cấu hình Collection để đảm bảo các trường title và content (nếu có) được lập chỉ mục theo kiểu text (full-text index) thay vì chỉ lưu trữ thô.
Thực thi lệnh cập nhật cấu hình Collection để bật Inverted Index:
curl --location "http://localhost:6333/collections/hybrid_docs/update" \
--header "Content-Type: application/json" \
--data '{
"payload_schema_diff": {
"title": {
"field_type": "text",
"params": {
"analyzer": "whitespace",
"min_token_len": 2,
"max_token_len": 100
}
},
"category": {
"field_type": "text",
"params": {
"analyzer": "keyword",
"min_token_len": 1,
"max_token_len": 100
}
}
}
}'
Kết quả mong đợi: API trả về "status": "ok". Lúc này, Qdrant đã tự động xây dựng inverted index cho các trường title và category, cho phép truy vấn nhanh theo từ khóa.
Verify kết quả
Kiểm tra cấu hình hiện tại của Collection để đảm bảo schema đã được cập nhật:
curl "http://localhost:6333/collections/hybrid_docs"
Quan sát phần "payload_schema" trong JSON trả về, đảm bảo title và category hiển thị "field_type": "text".
3. Thiết lập tham số Hybrid Search kết hợp Vector và Keyword
Bây giờ chúng ta đã có Collection với cấu hình payload và index đầy đủ, bước tiếp theo là thực hiện truy vấn Hybrid Search. Hybrid Search kết hợp sức mạnh của Vector Search (tìm kiếm ngữ nghĩa) và Keyword Search (tìm kiếm chính xác) thông qua bộ lọc payload.
Chúng ta sẽ gửi một truy vấn yêu cầu tìm các tài liệu liên quan đến từ khóa "tôi" (dùng vector embedding) nhưng chỉ giới hạn trong phạm vi category là "technology".
Giả sử bạn đã có vector embedding (dạng mảng float) cho câu hỏi "tôi muốn học AI". Thực thi lệnh truy vấn Hybrid:
curl --location "http://localhost:6333/collections/hybrid_docs/query" \
--header "Content-Type: application/json" \
--data '{
"query": {
"vector": [0.1, 0.2, 0.3, ...],
"shard_key": 0
},
"params": {
"score_threshold": 0.5,
"limit": 10
},
"filter": {
"must": [
{
"key": "category",
"match": {
"text": "technology"
}
}
]
},
"with_payload": true,
"with_vector": false
}'
Kết quả mong đợi: API trả về danh sách kết quả ("result") chỉ chứa các tài liệu có category là "technology" và có điểm tương đồng vector cao nhất với vector đầu vào. Các tài liệu thuộc category khác sẽ bị loại bỏ hoàn toàn.
4. Tinh chỉnh trọng số (weights) giữa Vector và Full-text
Trong các trường hợp phức tạp hơn, bạn muốn kết hợp hai phương pháp tìm kiếm độc lập: một phần dựa trên ngữ nghĩa (vector) và một phần dựa trên từ khóa chính xác (full-text search) rồi gộp kết quả lại. Qdrant hỗ trợ điều này qua cơ chế DisjunctionMax hoặc Weighted trong truy vấn.
Chúng ta sẽ cấu hình một truy vấn sử dụng HybridQuery (tính năng mới của Qdrant 1.x) cho phép chỉ định trọng số riêng biệt cho thành phần vector và thành phần keyword.
Thực thi lệnh truy vấn với trọng số tùy chỉnh: 70% trọng số cho Vector và 30% cho Keyword Search (dựa trên trường title):
curl --location "http://localhost:6333/collections/hybrid_docs/query" \
--header "Content-Type: application/json" \
--data '{
"query": {
"hybrid": {
"vector": [0.1, 0.2, 0.3, ...],
"sparse": {
"sparse_vector": {
"indices": [100, 200, 300],
"values": [0.8, 0.9, 0.7]
}
},
"weights": {
"vector": 0.7,
"sparse": 0.3
}
}
},
"params": {
"limit": 5,
"score_threshold": 0.1
},
"with_payload": true
}'
Lưu ý: Nếu không dùng sparse vector, bạn có thể dùng cấu trúc fusion để gộp hai kết quả tìm kiếm riêng biệt (một query vector, một query text) với trọng số xác định. Tuy nhiên, Qdrant hiện đại khuyến khích dùng cấu trúc hybrid trực tiếp nếu có sparse vector. Nếu chỉ dùng dense vector và text filter, hãy dùng cấu trúc filter kết hợp với query như mục 3, hoặc dùng fusion như sau:
Ví dụ sử dụng fusion để gộp kết quả tìm kiếm vector và tìm kiếm text (BM25) với trọng số:
curl --location "http://localhost:6333/collections/hybrid_docs/query" \
--header "Content-Type: application/json" \
--data '{
"query": {
"vector": [0.1, 0.2, 0.3, ...]
},
"params": {
"limit": 10,
"score_threshold": 0.0
},
"filter": {
"must": [
{
"key": "title",
"match": {
"text": "AI"
}
}
]
},
"with_payload": true
}'
Để tinh chỉnh trọng số thực sự giữa hai loại điểm số (score), bạn cần dùng tính năng Fusion (RRF hoặc DSC) trong phần params nếu thực hiện 2 query song song, hoặc dùng cấu hình weights trong hybrid query như trên nếu dùng sparse vector.
Verify kết quả
Kiểm tra điểm số (score) trong kết quả trả về. Nếu trọng số được điều chỉnh đúng, thứ tự kết quả sẽ thay đổi so với khi chỉ dùng vector search thuần túy. Các tài liệu khớp chính xác từ khóa "AI" trong tiêu đề sẽ có xu hướng đứng cao hơn nếu trọng số của phần text search được tăng lên.
curl "http://localhost:6333/collections/hybrid_docs/query?query=..." | jq '.result[].score'
So sánh danh sách điểm số trước và sau khi thay đổi tham số weights hoặc filter để xác nhận sự thay đổi thứ hạng.
Điều hướng series:
Mục lục: Series: Triển khai Database Vector đa mô hình với Qdrant trên Ubuntu 24.04
« Phần 2: Cấu hình cơ bản và quản lý Collection trong Qdrant
Phần 4: Tối ưu hiệu năng với bộ nhớ đệm và lập chỉ mục »