7.11 Query API và prefetch
Từ v1.10, Qdrant gộp năm endpoint tìm kiếm cũ (search, recommend, discover,
search_groups, …) vào một API duy nhất: query. Đây không chỉ là dọn dẹp API — nó
mở ra thứ mà trước đó phải làm ở tầng ứng dụng: một cascade nhiều tầng chạy trọn vẹn bên
trong database.
Ý tưởng: prefetch
Phần tiêu đề “Ý tưởng: prefetch”Quy tắc chỉ có một câu:
Nếu một truy vấn có
prefetch, Qdrant chạyprefetchtrước, rồi áp truy vấn chính lên kết quả của prefetch thay vì lên toàn bộ collection.
Và prefetch lồng nhau được. Từ đó ra toàn bộ sức mạnh của API này.
{ "prefetch": { "prefetch": { "query": <vector rẻ>, "limit": 1000 }, ← tầng 1: quét rộng, rẻ "query": <vector đầy đủ>, "limit": 100 ← tầng 2: thu hẹp }, "query": <multivector ColBERT>, "limit": 10 ← tầng 3: xếp lại, đắt}Đây chính là kiến trúc hai (ba) giai đoạn của 5.1 — dùng cái rẻ để thu hẹp, dùng cái đắt để quyết định — nhưng chạy trong một request, không phải ba vòng qua mạng.
Bốn kiểu cascade thường dùng
Phần tiêu đề “Bốn kiểu cascade thường dùng”| Kiểu | Tầng 1 | Tầng cuối | Được gì |
|---|---|---|---|
| Nén → gốc | vector đã quantization | vector float đầy đủ | Đây chính là rescore của 7.10, viết tường minh |
| Ngắn → dài | 256 chiều đầu (Matryoshka) | vector đầy đủ | Tầng 1 rẻ hơn nhiều lần |
| Dense → ColBERT | dense 1 vector | multivector max_sim | Late interaction mà không cần dịch vụ rerank riêng |
| Dense + sparse → fusion | hai prefetch song song | fusion | Hybrid — xem 7.12 |
Ba kiểu đầu là rescoring: một prefetch, một truy vấn chính chấm điểm lại. Kiểu thứ tư là fusion: nhiều prefetch song song, fusion thứ hạng.
Mẹo RAM đi kèm. Vector chỉ dùng ở tầng cuối (ColBERT, vector float gốc khi tầng 1 là bản nén) không cần đồ thị HNSW — rescore không đi qua HNSW. Đặt
m: 0cho named vector đó. Xem 7.3 và 7.7.
Hai cái bẫy phải biết trước khi dùng
Phần tiêu đề “Hai cái bẫy phải biết trước khi dùng”1. limit của prefetch phải đủ lớn
Phần tiêu đề “1. limit của prefetch phải đủ lớn”offset chỉ áp lên truy vấn chính, không áp lên prefetch. Nghĩa là:
Mỗi prefetch phải có
limitít nhất bằnglimit + offsetcủa truy vấn chính. Nếu không, bạn có thể nhận về kết quả rỗng.
Đây là bug điển hình khi làm phân trang trên hybrid search: trang 1 ổn, trang 5 trống rỗng.
2. limit của tầng 1 là trần recall của cả truy vấn
Phần tiêu đề “2. limit của tầng 1 là trần recall của cả truy vấn”Đây không phải chuyện riêng của Qdrant — nó là 5.4 phát biểu lại bằng cú pháp Query API:
Tầng cuối không tìm được thứ mà tầng 1 chưa đưa cho nó. Nếu prefetch lấy 100 và đáp án đúng đứng hạng 137, thì ColBERT có giỏi đến mấy cũng vô ích.
Cách chọn limit cho tầng 1 vẫn là cách của 5.4: đo recall@k của riêng tầng 1 với
nhiều giá trị k, tìm điểm mà đường cong bắt đầu phẳng, lấy giá trị đó.
Hai API đọc không phải “tìm kiếm”
Phần tiêu đề “Hai API đọc không phải “tìm kiếm””Chúng dễ bị bỏ quên nhưng rất hay dùng trong vận hành:
scroll — duyệt tuần tự theo filter, không cần vector. Kết quả sắp theo ID, và
phân trang bằng next_page_offset (khi nó null là hết). Dùng để: kiểm dữ liệu, xoá hàng
loạt theo điều kiện, tái xử lý.
Từ v1.19 có điều kiện slice cho phép chia collection thành các phần rời nhau xác định,
nên nhiều worker có thể duyệt song song mà không giẫm chân nhau — cách này tốt hơn hẳn
phân trang tuần tự khi cần quét lại toàn bộ.
count — mặc định là ước lượng, vì đếm chính xác đòi quét. Đặt exact: true khi
bạn thật sự cần con số đúng.
⚠️
points_counttrả về trong thông tin collection cũng là con số xấp xỉ. Đừng dùng nó để đối chiếu số lượng bản ghi với hệ nguồn rồi kết luận là mất dữ liệu.
Chọn dùng gì
Phần tiêu đề “Chọn dùng gì”| Bạn cần | Dùng |
|---|---|
| Tìm giống nhất | query với một vector |
| Tìm giống nhất theo từ khoá | query với sparse vector |
| Cả hai | query + hai prefetch + fusion (7.12) |
| Tìm rẻ rồi chấm lại đắt | query + prefetch lồng nhau |
| Lấy dữ liệu theo điều kiện, không cần vector | scroll |
| Đếm | count (nhớ exact) |
| Gom nhóm, đếm theo giá trị | → 7.14 |