Vector DB deep — embedding, cosine similarity, ANN index, 6 platform 2026

Vector DB lưu embedding vector + search semantic 'nearest neighbor' siêu nhanh. Foundation cho RAG + semantic search + recommendation. Hiểu sâu HNSW vs IVF index, cosine vs dot product, hybrid search, sharding, 6 platform (Pinecone/Qdrant/Weaviate/pgvector/Chroma/Milvus) — chọn đúng theo scale.

11 phút đọcCập nhật 2026-05-23
Nghe bài viết
Để Claude đọc bài cho bạn — vừa nghe vừa làm việc khác
Mục lục bài viết(31)
Sơ đồ word embedding — từ ngữ map thành vector trong space đa chiều, từ tương tự gần nhau

Sơ đồ word embedding — mỗi từ map thành vector số trong space 384-3072 dimensions. Từ ngữ nghĩa tương tự ("king" và "queen", "cat" và "dog") nằm GẦN nhau trong space. Vector DB optimize search "nearest neighbor" — tìm top-K vector gần nhất với query vector trong milliseconds dù có 100M+ vector. Foundation cho RAG, semantic search, recommendation engine. Nguồn: Wikimedia Commons (CC BY-SA 4.0).

Hiểu đơn giản nhất

Tưởng tượng bạn có thư viện 10 triệu cuốn sách. User hỏi "cho tôi cuốn về AI tương tự cuốn 'Deep Learning' của Goodfellow".

Cách cũ — keyword search: SQL LIKE '%AI%' → return 100k cuốn có chữ "AI" → quá nhiều, không relevant.

Cách mới — vector search:

  1. Convert "Deep Learning" book → vector 1536 chiều (encode "ý nghĩa")
  2. Search top 10 vector GẦN NHẤT trong 10M vector → return cuốn "Pattern Recognition" (Bishop), "Machine Learning" (Mitchell), "Reinforcement Learning" (Sutton)... — actually relevant.
  3. Speed: 5-20ms cho 10M vector với HNSW index

Vector DB = database optimize cho việc lưu + search embedding vector.

Concepts cốt lõi

Khái niệmVai trò
EmbeddingVector 384-3072 dim encode "ý nghĩa" của text/image
Cosine similarityĐo distance giữa 2 vector (0=identical, 1=opposite)
ANN indexSpeed up search O(N) → O(log N)
HNSWMost popular index, fast + accurate
Top-K searchReturn K vectors closest to query
Metadata filterFilter results theo field (tenant, date, type)
ChunkingSplit document thành chunk 500-800 token
Hybrid searchCombine semantic + keyword (BM25)

Tại sao bạn cần biết

  • Foundation RAG. Mọi RAG implementation cần vector DB. Bài RAG là gì cover overview, bài này deep dive vector DB.
  • Semantic search beyond RAG. E-commerce "find similar products", music "songs like X", customer support "similar tickets" — đều vector search.
  • Cost optimization critical. Wrong DB choice = 10-100x cost. Pinecone managed $70+/tháng vs pgvector free.
  • Performance bottleneck. Bad chunking + bad index = slow query → bad UX. Hiểu để tune.
  • Multi-tenancy + security. Cross-tenant leak qua vector search là attack vector mới — hiểu để defend.

Embedding — convert text to vector

Embedding model = neural network encode meaning into vector.

// OpenAI text-embedding-3-small
const response = await openai.embeddings.create({
  model: "text-embedding-3-small",
  input: "Vietcodex là agency dev AI-native"
});
 
const vector = response.data[0].embedding;
// vector: [0.012, -0.034, 0.045, ..., 0.023] — 1536 floats

Embedding model comparison 2026

ModelDimPriceStrength
OpenAI text-embedding-3-small1536$0.02/MDefault, balanced
OpenAI text-embedding-3-large3072$0.13/MHighest English accuracy
Voyage AI voyage-31024$0.06/MOutperform OpenAI MTEB
Cohere embed-v3-multilingual1024$0.10/MStrong multilingual including VN
BGE-M3 (open-source)1024Free (self-host GPU)Top OSS, 100+ language
Anthropic native embedding1024$0.05/MIntegrate Claude seamlessly
Gemini embedding-001768$0.025/MGoogle ecosystem

Vietnamese-specific test: Voyage v3 và Cohere v3 outperform OpenAI ~10-15% trên VN content benchmark.

Cosine Similarity vs Dot Product vs Euclidean

// Vector a = [0.5, 0.3, 0.8]
// Vector b = [0.4, 0.4, 0.9]
 
// Cosine similarity (most common cho text)
const cosine = dot(a, b) / (norm(a) * norm(b));
// 0.987 — very similar
 
// Dot product (faster, requires normalized vectors)
const dotScore = dot(a, b);
// 0.92
 
// Euclidean distance (less common cho text)
const euclidean = sqrt(sum((a[i] - b[i])^2));
// 0.17 — small distance = similar

Quy tắc:

  • Text embedding (OpenAI, Voyage, Cohere) → Cosine hoặc Dot (nếu normalized)
  • Image embedding (CLIP, DINO) → Cosine
  • Geographic coordinates → Euclidean

Vector DB default cosine cho safety.

ANN Index — HNSW vs IVF

Naive search: O(N) — không scale

Query vector + 10M vectors:
  Compute cosine với từng vector → 10M operations
  At 1µs each: 10 seconds/query — UNUSABLE

HNSW (Hierarchical Navigable Small World)

Multi-layer graph: top layer sparse (long edges), bottom layer dense (short edges).

Top layer:      A ─────────── C ─────── F        ← skip long distances
                │             │         │
Mid layer:      A ── B ─── C ── D ── F            ← refine
                │   │     │    │    │
Bottom layer:   A-B-B-C-C-D-D-E-E-F-F-G-G-H-H...  ← exhaustive local

Search:

  1. Start top layer, hop to nearest
  2. Go down layer, refine
  3. Bottom layer = top-K results

Speed: 5-20ms cho 10M vector Recall: 95-99% Memory: ~3x raw vector size Best for: < 100M vector, abundant RAM

IVF (Inverted File Index)

Cluster vectors thành K bucket (vd K=1000). Query → identify nearest cluster → search only that bucket.

Cluster 1: [v1, v3, v5, ...]
Cluster 2: [v2, v8, v15, ...]
...
Cluster K: [vN-1, vN]

Query: find nearest cluster (K cosine ops) → search nprobe=10 buckets

Speed: 10-50ms Recall: 90-95% Memory: ~1.2x raw Best for: > 100M vector, memory constraint

IVF-PQ (Quantized) — extreme scale

Combine IVF + Product Quantization (compress vector 32 bit → 8 bit). Trade recall for storage.

Memory: ~10x smaller Recall: 85-92% Best for: > 1B vector (Pinterest, Spotify scale)

6 Vector DB platform 2026

1. Pinecone (managed SaaS — easiest)

import { Pinecone } from "@pinecone-database/pinecone";
 
const pc = new Pinecone({ apiKey: process.env.PINECONE_KEY });
const index = pc.index("vietcodex-docs");
 
// Upsert
await index.upsert([{
  id: "chunk-001",
  values: embedding,  // [0.12, -0.34, ...]
  metadata: { doc_id: "wiki-001", chunk_index: 0, tenant: "vc-abc" }
}]);
 
// Query
const results = await index.query({
  vector: queryEmbedding,
  topK: 5,
  includeMetadata: true,
  filter: { tenant: { $eq: "vc-abc" } }
});

Pricing: Free 100k vector, $70+/tháng paid Strengths: Easiest, hosted, multi-tenant native Weaknesses: Expensive at scale, no self-host

2. Qdrant (open-source Rust)

import { QdrantClient } from "@qdrant/js-client-rest";
 
const client = new QdrantClient({ url: "http://localhost:6333" });
 
await client.upsert("docs", {
  points: [{
    id: "chunk-001",
    vector: embedding,
    payload: { doc_id: "wiki-001", tenant: "vc-abc" }
  }]
});
 
const results = await client.search("docs", {
  vector: queryEmbedding,
  limit: 5,
  filter: { must: [{ key: "tenant", match: { value: "vc-abc" } }] }
});

Pricing: Free self-host, $25+/tháng cloud Strengths: Fast (Rust), sparse vectors (hybrid), production-ready Weaknesses: Less mature ecosystem than Pinecone

3. Weaviate (open-source, GraphQL)

query {
  Get {
    Article(
      nearVector: { vector: [0.12, -0.34, ...] }
      where: { path: ["tenant"], operator: Equal, valueString: "vc-abc" }
      limit: 5
    ) {
      title
      _additional { distance }
    }
  }
}

Pricing: Free self-host, $25+/tháng cloud Strengths: Hybrid search built-in, GraphQL API, schema-aware Weaknesses: Verbose API, JVM (resource intensive)

4. pgvector (Postgres extension — FREE)

-- Setup
CREATE EXTENSION vector;
CREATE TABLE docs (
  id TEXT PRIMARY KEY,
  content TEXT,
  embedding VECTOR(1536),
  tenant TEXT
);
CREATE INDEX ON docs USING hnsw (embedding vector_cosine_ops);
 
-- Query
SELECT id, content, 1 - (embedding <=> $1::vector) AS similarity
FROM docs
WHERE tenant = 'vc-abc'
ORDER BY embedding <=> $1::vector
LIMIT 5;

Pricing: Free (đã có Postgres) Strengths: Use existing DB, ACID, joins với relational data Weaknesses: Performance lower scale > 10M, less specialized

vietcodex.com đang dùng pgvector — đủ cho < 100k chunk hiện tại.

5. Chroma (Python embedded)

import chromadb
 
client = chromadb.Client()
collection = client.create_collection("docs")
 
collection.add(
    embeddings=[embedding],
    documents=["..."],
    metadatas=[{"tenant": "vc-abc"}],
    ids=["chunk-001"]
)
 
results = collection.query(
    query_embeddings=[query_embedding],
    n_results=5,
    where={"tenant": "vc-abc"}
)

Pricing: Free OSS, embedded Python Strengths: Easiest dev experience, in-memory mode Weaknesses: Less production-ready, Python-focused

Best for: Local dev, prototype, < 1M vector.

6. Milvus (enterprise scale)

Tencent + Zilliz cloud version. Used at billion-vector scale.

Pricing: Free self-host (complex deploy), Zilliz Cloud $99+/tháng Strengths: Billion-scale, GPU support, distributed Weaknesses: Operational complexity, overkill cho < 100M

Quyết định ma trận

ScaleRecommendation
< 100k vector + đã có Postgrespgvector (free)
< 1M vector + Python devChroma local
100k-10M + Cloud-firstQdrant Cloud ($25+) hoặc Pinecone ($70+)
10M-100M + Self-hostQdrant hoặc Weaviate self-host
100M-1B + EnterpriseMilvus hoặc Pinecone Enterprise
Hybrid search criticalWeaviate hoặc Qdrant (sparse vectors)
TS/Node appPinecone SDK best, hoặc pgvector
Python ML stackChroma dev → Qdrant prod

Chunking deep — 4 strategy

1. Fixed-size + overlap

def chunk_fixed(text, chunk_size=500, overlap=50):
    chunks = []
    for i in range(0, len(text), chunk_size - overlap):
        chunks.append(text[i:i + chunk_size])
    return chunks

Pros: simple, predictable Cons: cắt giữa sentence/code

2. Sentence-based

import nltk
sentences = nltk.sent_tokenize(text)
 
chunks = []
current_chunk = []
current_size = 0
for s in sentences:
    if current_size + len(s) > 800:
        chunks.append(" ".join(current_chunk))
        current_chunk = []
        current_size = 0
    current_chunk.append(s)
    current_size += len(s)

Pros: respect natural boundary Cons: uneven chunk size

3. Recursive (LangChain default)

Split theo hierarchy: \n\n\n → ký tự.

from langchain.text_splitter import RecursiveCharacterTextSplitter
 
splitter = RecursiveCharacterTextSplitter(
    chunk_size=800,
    chunk_overlap=100,
    separators=["\n\n", "\n", ".", " "]
)
chunks = splitter.split_text(text)

Pros: smart, work cho hầu hết doc Cons: slightly slower

4. Semantic (LlamaIndex SemanticSplitter)

Embed each sentence, detect topic shift via embedding similarity drop.

Pros: best precision Cons: slow + expensive (embed during ingest)

Hybrid search implementation

Weaviate built-in

query {
  Get {
    Article(
      hybrid: {
        query: "GPT-4o pricing"
        vector: [0.12, ...]
        alpha: 0.5  # 0 = keyword only, 1 = vector only
      }
      limit: 5
    ) { title }
  }
}

pgvector + tsvector combine

WITH semantic AS (
  SELECT id, embedding <=> $1 AS distance
  FROM docs
  ORDER BY distance
  LIMIT 20
),
keyword AS (
  SELECT id, ts_rank(tsv, plainto_tsquery($2)) AS score
  FROM docs
  WHERE tsv @@ plainto_tsquery($2)
  ORDER BY score DESC
  LIMIT 20
)
SELECT id, 
  (COALESCE(1.0 / (rank_semantic + 60), 0) + COALESCE(1.0 / (rank_keyword + 60), 0)) AS rrf_score
FROM (
  SELECT id, ROW_NUMBER() OVER (ORDER BY distance) AS rank_semantic FROM semantic
) s
FULL JOIN (
  SELECT id, ROW_NUMBER() OVER (ORDER BY score DESC) AS rank_keyword FROM keyword
) k USING (id)
ORDER BY rrf_score DESC
LIMIT 5;

Reciprocal Rank Fusion (RRF) combine 2 ranking.

Ví dụ thực tế: vietcodex.com wiki RAG pipeline

Stack:
  - Embedding: OpenAI text-embedding-3-small ($0.02/M)
  - Vector DB: pgvector (Postgres extension, free)
  - Chunk: Recursive splitter 700 token + 50 overlap
  - Search: Hybrid (cosine semantic + tsvector BM25, RRF)
  - Result: top-5 chunk + metadata

Ingest pipeline (run mỗi deploy):
  - Parse 67 wiki MDX → strip frontmatter + markdown formatting
  - Recursive chunk → ~800 chunk total
  - Embed each chunk → $0.02 × 0.4M = $0.008
  - Upsert pgvector

Query pipeline:
  - User query: "Cookies vs Token khác nhau"
  - Embed query (50 token): negligible cost
  - Hybrid search → top-5 chunk
  - Inject vào prompt as RAG context
  - LLM augment + generate response
  
Cost/query: ~$0.01 (Claude Sonnet 4.5 với cached system prompt)
Latency: ~150ms (pgvector + LLM streaming start)

Cái gì có thể sai

Vấn đềTriệu chứngCách fix
Search precision thấpWrong chunk sizeA/B test 300/500/800 token
Slow query > 1sNo index hoặc index sai typeAdd HNSW index, verify EXPLAIN
Cross-tenant leakMetadata filter miss in queryAudit every query include tenant filter
Embedding cost caoRe-embed mọi updateIncremental — only changed doc
Vietnamese poor matchOpenAI embedding EN-biasedSwitch Voyage v3 hoặc Cohere v3
Memory blow upHNSW + 100M vectorSwitch IVF hoặc IVF-PQ
Stale embeddingDoc updated nhưng vector cũWebhook trigger re-embed on change
Bias toward long docTF-IDF score biasNormalize by chunk length

Tóm tắt 1 dòng

Vector DB lưu embedding + search "nearest neighbor" semantic siêu nhanh. Foundation RAG + semantic search + recommendation. Concepts: embedding (1024-3072 dim), cosine similarity, HNSW index (95%+ recall, <100M vector), IVF (>100M scale). 6 platform 2026: Pinecone (managed easy), Qdrant (Rust fast OSS), Weaviate (GraphQL hybrid), pgvector (free Postgres extension — vietcodex dùng), Chroma (Python dev), Milvus (billion scale). Embedding model VN: Voyage v3 > Cohere v3 > OpenAI. Chunking 500-800 token + overlap 50. Hybrid search semantic + BM25 RRF tăng precision 10-30%.

Đọc tiếp

Câu hỏi thường gặp

Vector DB và NoSQL khác nhau gì?
NoSQL (MongoDB, DynamoDB): document storage, query by field exact match hoặc range. Vector DB: lưu embedding vector (array 384-3072 dimensions float) + search by SIMILARITY (cosine/dot product). NoSQL hỏi 'doc có field name=John'. Vector DB hỏi 'top 10 doc semantic gần với query embedding này'. Vector DB optimize index ANN (Approximate Nearest Neighbor) thay vì B-tree NoSQL. Modern DB hybrid: Postgres + pgvector extension, MongoDB Atlas Vector Search — chạy cả 2 trong cùng DB.
Cosine similarity vs Dot product vs Euclidean — chọn cái nào?
(1) **Cosine similarity** — đo angle giữa 2 vector, ignore magnitude. Range -1 to 1. Best cho text embedding (most common). (2) **Dot product** — multiply vector element-wise, sum. Faster compute hơn cosine. Use khi embedding đã normalized to unit length (OpenAI text-embedding-3, Cohere embed-v3 đều normalize). (3) **Euclidean distance** — distance trong N-dimensional space. Less common cho text. Quy tắc 2026: text embedding → cosine HOẶC dot product (nếu normalized). Image embedding → cosine. Most vector DB default cosine.
HNSW vs IVF index — khác gì?
Index ANN (Approximate Nearest Neighbor) — speedup search từ O(N) → O(log N). (1) **HNSW** (Hierarchical Navigable Small World) — multi-layer graph, fast query, accuracy 95%+. Pros: speed, accuracy. Cons: memory hungry (~3x raw vector size). Most popular 2026. (2) **IVF** (Inverted File Index) — cluster vectors thành K bucket, query search top bucket. Pros: memory efficient. Cons: lower recall (90%). Quy tắc: < 10M vector + abundant RAM → HNSW. > 100M vector + memory constraint → IVF hoặc IVF-PQ (quantized). Pinecone/Qdrant default HNSW.
Embedding model — chọn cái nào 2026?
(1) **OpenAI text-embedding-3-small** ($0.02/M token) — 1536 dim, balanced speed/quality, default choice; (2) **OpenAI text-embedding-3-large** ($0.13/M) — 3072 dim, highest accuracy English; (3) **Voyage AI voyage-3** ($0.06/M) — outperform OpenAI trên MTEB benchmark, good multilingual; (4) **Cohere embed-v3** ($0.10/M) — strong multilingual including Vietnamese; (5) **BGE-M3** (open-source, self-host GPU) — free, top open-source, support 100+ languages; (6) **Anthropic native embedding** (launched 2025) — integrate seamlessly Claude. Quy tắc Vietnamese: Voyage AI hoặc Cohere v3 > OpenAI cho VN content. Test với eval set của bạn — MTEB benchmark không hoàn toàn reflect VN.
Hybrid search — kết hợp semantic + keyword thế nào?
Pure semantic miss exact match: user search 'GPT-4o' nhưng doc 'GPT 4o' (space) → embedding gần nhưng không exact. Pure keyword (BM25) miss synonym. Hybrid: chạy cả 2, combine via Reciprocal Rank Fusion (RRF). RRF formula: score = Σ(1 / (rank + k)) với k=60 thường. Improvement precision +10-30%. Implementation: (1) Weaviate built-in `hybrid_query()`; (2) Qdrant 1.10+ sparse vectors; (3) pgvector custom: combine BM25 (tsvector) + cosine; (4) Pinecone `sparse-dense vectors` 2024. Default cho RAG production 2026.
Chunking strategy ảnh hưởng vector DB performance thế nào?
Chunk size impact 3 thứ: (1) **Search precision** — chunk nhỏ (200 token) precision cao nhưng miss context, chunk to (1000 token) context tốt nhưng dilute meaning; (2) **Embedding cost** — chia 1 doc thành 10 chunk thay 5 = 2x cost embedding; (3) **Storage** — vector DB size tăng tuyến tính theo chunk count. Best practice: chunk 500-800 token + overlap 50 token (avoid splitting mid-sentence). Recursive splitter (LangChain) work cho hầu hết text. Semantic chunking (LlamaIndex SemanticSplitter) cho document có topic shift rõ ràng. Test với eval set retrieval recall, không assume.
Multi-tenancy + RBAC trong vector DB thế nào?
3 pattern: (1) **Namespace per tenant** (Pinecone) — separate vector pool, simple; (2) **Metadata filter** — single index, filter by tenant_id at query time. Pros: efficient. Cons: cross-tenant leak risk nếu filter sai; (3) **Separate collection per tenant** (Qdrant, Milvus) — strong isolation. Pros: secure. Cons: management overhead nếu > 1000 tenant. RBAC: combine với metadata `user_role`, filter retrieve theo role. Pattern vietcodex.com: namespace per tenant cho enterprise B2B, metadata filter cho B2C. Audit critical — log mỗi query include tenant + user.