Sổ tay kỹ thuật

Vector DB cheatsheet (pgvector, Qdrant)

cheatsheet#rag#postgresql#python· cập nhật 2026-11-06

Tra nhanh lệnh pgvector (extension, kiểu vector, index HNSW/IVFFlat, toán tử khoảng cách) và Qdrant (collection, upsert, search có filter) khi dựng RAG.

Sửa trang này
Mục lục

Lệnh hay dùng để lưu và truy vấn embedding. Pipeline RAG tổng thể (chunking, embedding, rerank) xem RAG cơ bản. Số chiều trong ví dụ là 1024: thay bằng số chiều của model embedding bạn dùng.

pgvector: cài và tạo bảng

Mục đích Lệnh
Bật extension (mỗi database) CREATE EXTENSION IF NOT EXISTS vector;
Xem phiên bản SELECT extversion FROM pg_extension WHERE extname = 'vector';
Chạy nhanh bằng Docker docker run -d -p 5432:5432 -e POSTGRES_PASSWORD=$PGPASSWORD pgvector/pgvector:pg17
Cột embedding embedding vector(1024)
Tiết kiệm bộ nhớ (float16) embedding halfvec(1024)
CREATE TABLE doc_chunks (
  id        bigserial PRIMARY KEY,
  source    text NOT NULL,             -- vd runbook/bgp.md
  vendor    text,                      -- iosxr / junos, dùng để filter
  content   text NOT NULL,
  embedding vector(1024) NOT NULL
);
INSERT INTO doc_chunks (source, vendor, content, embedding)
VALUES ('runbook/bgp.md', 'iosxr', 'Kiểm tra hold timer...', '[0.012, -0.034, ...]');

pgvector: toán tử khoảng cách

Toán tử Khoảng cách Operator class cho index
<-> L2 (Euclid) vector_l2_ops
<=> Cosine distance (= 1 - cosine similarity) vector_cosine_ops
<#> Inner product âm (nhân -1 để ra inner product) vector_ip_ops
<+> L1 (Manhattan, từ pgvector 0.7) vector_l1_ops
-- top 5 chunk gần nhất theo cosine, có filter
SELECT id, source, 1 - (embedding <=> $1) AS similarity
FROM doc_chunks
WHERE vendor = 'iosxr'
ORDER BY embedding <=> $1
LIMIT 5;

Index chỉ được dùng khi có ORDER BY embedding <op> ... LIMIT n với đúng toán tử khớp operator class của index. Embedding đã chuẩn hoá (norm = 1) thì cosine và inner product cho cùng thứ tự kết quả.

pgvector: index

Mục đích Lệnh
HNSW (chính xác cao, build chậm, không cần dữ liệu trước) CREATE INDEX ON doc_chunks USING hnsw (embedding vector_cosine_ops);
HNSW chỉnh tham số ... USING hnsw (embedding vector_cosine_ops) WITH (m = 16, ef_construction = 64);
Tăng recall khi query HNSW SET hnsw.ef_search = 100; (mặc định 40)
IVFFlat (build nhanh, nên tạo sau khi đã có dữ liệu) CREATE INDEX ON doc_chunks USING ivfflat (embedding vector_cosine_ops) WITH (lists = 100);
Tăng recall khi query IVFFlat SET ivfflat.probes = 10; (mặc định 1)
Tăng bộ nhớ khi build index SET maintenance_work_mem = '2GB';
Xem query có dùng index EXPLAIN ANALYZE SELECT ... ORDER BY embedding <=> $1 LIMIT 5;

Gợi ý lists cho IVFFlat: khoảng rows / 1000 nếu dưới 1 triệu dòng. Index HNSW/IVFFlat cho kiểu vector giới hạn tối đa 2000 chiều. Model nhiều chiều hơn thì dùng halfvec (index được tới 4000 chiều).

Qdrant: chạy và tạo collection

Mục đích Lệnh
Chạy bằng Docker (REST 6333, gRPC 6334) docker run -d -p 6333:6333 -p 6334:6334 -v $(pwd)/qdrant_storage:/qdrant/storage qdrant/qdrant
Cài client Python uv add qdrant-client
Liệt kê collection curl -s localhost:6333/collections
Thông tin collection (số point, config) curl -s localhost:6333/collections/runbooks
Xoá collection curl -X DELETE localhost:6333/collections/runbooks
curl -X PUT localhost:6333/collections/runbooks \
  -H 'Content-Type: application/json' \
  -d '{"vectors": {"size": 1024, "distance": "Cosine"}}'

Qdrant: upsert và search (Python)

from qdrant_client import QdrantClient
from qdrant_client.models import (Distance, FieldCondition, Filter, MatchValue,
                                  PointStruct, VectorParams)
 
qc = QdrantClient(url="http://localhost:6333")
qc.create_collection("runbooks", vectors_config=VectorParams(size=1024, distance=Distance.COSINE))
qc.create_payload_index("runbooks", field_name="vendor", field_schema="keyword")  # filter nhanh hơn
 
qc.upsert("runbooks", points=[
    PointStruct(id=1, vector=emb, payload={"source": "runbook/bgp.md", "vendor": "iosxr", "text": chunk}),
])
 
hits = qc.query_points(
    "runbooks",
    query=query_emb,
    query_filter=Filter(must=[FieldCondition(key="vendor", match=MatchValue(value="iosxr"))]),
    limit=5,
    with_payload=True,
).points
for h in hits:
    print(h.score, h.payload["source"])
Khái niệm Qdrant Tương đương pgvector
Collection Bảng
Point (id + vector + payload) Dòng
Payload filter (must, should, must_not) WHERE
distance: Cosine / Dot / Euclid / Manhattan <=> / <#> / <-> / <+>
score (Cosine: càng lớn càng gần) 1 - (a <=> b)

ID của point Qdrant phải là số nguyên không âm hoặc UUID. Chuỗi tuỳ ý như "bgp.md#3" sẽ bị từ chối: hãy sinh UUID từ chuỗi đó (uuid.uuid5).