Bỏ qua để đến nội dung
Search & RAG

7.1 Qdrant là gì, và khi nào đừng dùng

Câu trả lời ngắn: Qdrant là một cơ sở dữ liệu chuyên đi tìm hàng xóm gần nhất trong không gian vector, kèm khả năng lọc theo metadata mà không làm hỏng phép tìm đó.

Vế sau của câu là phần đắt giá. Đi tìm hàng xóm gần nhất thì thư viện nào cũng làm được — FAISS, hnswlib, thậm chí vài chục dòng NumPy. Việc khó là làm chuyện đó trong khi dữ liệu vẫn đang thay đổi, và người dùng vẫn đang thêm điều kiện lọc. Đó là ranh giới giữa một thư viện ANN và một vector database, và cũng là chỗ 7.8 sẽ đào rất sâu.

1.3 đã tách ba loại model. Đây là lát cắt tương ứng cho ba loại hạ tầng:

Thư viện ANNVector databaseSearch engine đầy đủ
Ví dụFAISS, hnswlib, ScaNNQdrant, Milvus, WeaviateElasticsearch, Vespa, OpenSearch
Đơn vị bạn thao tácmảng vector trong RAM tiến trình của bạnđiểm có ID + metadata, qua mạngtài liệu có schema, qua mạng
Xoá/sửa một phần tửthường phải dựng lại indexcó, trực tuyếncó, trực tuyến
Lọc theo metadatatự làm ở ngoàicó, trong lúc tìmcó, rất mạnh
Bền vững sau khi tắt máytự lưu filecó (WAL + snapshot)
Phân tántự làm

Qdrant không là một search engine đầy đủ. Nó có full-text search, nhưng đó là công cụ lọcsparse retrieval, không phải một Lucene thay thế: không có analyzer chain kiểu Elasticsearch, không có aggregation phong phú, không có query DSL cho văn bản ở mức đó. Nếu bài toán của bạn thật sự là tìm kiếm văn bản truyền thống, hãy đọc lại 3.14 — Bảng chọn cấu trúc trước.

Ba trường hợp, xếp theo mức độ hay gặp:

1. Dữ liệu của bạn còn nhỏ, và bạn đã có Postgres. Dưới khoảng vài trăm nghìn đến vài triệu vector, pgvector thường là lựa chọn đúng: không thêm hạ tầng, không thêm một hệ thống nữa phải backup và giám sát, và bạn được transaction thật — vector và dữ liệu nghiệp vụ nằm trong cùng một lần commit. Cái giá bạn trả là hiệu năng ở đuôi phân phối và khả năng lọc trong lúc tìm. Đó thường là cái giá rẻ, cho tới khi nó không rẻ nữa.

2. Bạn chưa đo được stage 1 đang hỏng ở đâu. Đổi từ một for loop cosine sang Qdrant không cải thiện chất lượng. Nó cải thiện tốc độkhả năng vận hành. Nếu recall@k của bạn thấp thì nguyên nhân gần như luôn nằm ở chunking, embedding, hoặc truy vấn — không nằm ở việc bạn đang dùng NumPy thay vì HNSW. Xem 5.4 — Trần recall@k.

3. Bạn thật sự cần quy mô tỷ vector và có đội vận hành riêng. Ở mức đó, kiến trúc tách compute/storage của Milvus và các hệ tương tự có lý do tồn tại. Qdrant chạy được ở quy mô lớn, nhưng nó là một hệ stateful, tự quản shard, không phải một hệ dựng trên object storage.

Bảng dưới là định tính, tổng hợp từ tài liệu chính thức và các so sánh 2026 trong mục Đọc thêm, không phải số đo của cẩm nang. Đừng dùng nó thay cho việc đo trên dữ liệu của bạn:

Điểm mạnh riêngĐiểm yếu / cái giá
QdrantLọc + vector search làm chung một bước rất tốt; Rust nên tiết kiệm bộ nhớ; self-host dễ; API truy vấn thống nhấtKhông có hệ sinh thái text search sâu; phân tán do bạn tự quản shard
pgvectorBạn đã có Postgres; transaction thật; zero hạ tầng mớiĐuối dần khi vector nhiều; filter + ANN kém tinh vi hơn
WeaviateVectorizer cắm sẵn, hybrid BM25 có sẵn theo kiểu “bật là chạy”Ràng buộc vào mô hình schema của nó
MilvusKiến trúc phân tán cho quy mô rất lớn, GPU indexVận hành nặng; thừa cho phần lớn hệ RAG
Elasticsearch / OpenSearchText search trưởng thành, aggregation, đã có sẵn trong nhiều công tyIndexing vector chậm hơn đáng kể; ANN là tính năng thêm vào, không phải lõi

Câu hỏi đúng không phải “cái nào tốt nhất” mà là: bạn đang đau ở đâu? Đau vì recall thì đổi database không chữa. Đau vì latency ở tail khi có filter thì đây đúng là chỗ Qdrant khác biệt.

Ba quyết định thiết kế xuyên suốt phần này, nêu trước để bạn có khung khi đọc tiếp:

  1. Không có “một index cho cả collection”. Dữ liệu chia thành nhiều segment, mỗi segment mang index riêng, và một tiến trình nền (optimizer) liên tục sắp xếp lại chúng. Gần như mọi hành vi latency khó hiểu đều truy về câu này.
  2. Filter được đưa vào trong đồ thị HNSW, chứ không đặt trước hay đặt sau nó (7.8).
  3. Mặc định nghiêng về availability và throughput, không phải consistency (7.16). Đọc ngay sau khi ghi có thể chưa thấy dữ liệu, và đó là thiết kế chứ không phải lỗi.
Phần 7 — Qdrant