What is a vector database?

A vector database stores embeddings and enables fast approximate nearest-neighbour search - finding the most semantically similar items to a query vector at scale.

AIVector DatabaseRAG

Overview

Traditional databases find exact matches. Vector databases find approximate nearest neighbours - the most semantically similar items to a query in a high-dimensional embedding space. They are the storage and retrieval layer in RAG systems and semantic search engines. Instead of indexing string values, they index floating-point vectors and use specialised algorithms (HNSW, IVF) to search millions of vectors in milliseconds.

Key Points

  • •Core operation: given a query vector, return the top-K vectors with the smallest distance (cosine or dot product similarity).
  • •All vector databases support metadata filtering: "find the top-5 most similar chunks where `source = 'policy.pdf'`".
  • •HNSW (Hierarchical Navigable Small World) is the most common index algorithm - fast approximate search with high recall.
  • •Popular options: **Pinecone** (managed cloud), **pgvector** (PostgreSQL extension), **Chroma** (local/OSS), **Weaviate**, **Qdrant**, **Milvus**.
  • •For small datasets (<100k vectors), an in-memory search over all vectors is often fast enough - no vector DB needed.
  • •Vector DBs are not a replacement for regular databases - use both together: metadata in SQL, vectors in a vector index.

Examples

pgvector - vector search inside PostgreSQL

sql
-- Enable the extension
CREATE EXTENSION IF NOT EXISTS vector;

-- Create a table with a vector column (1536 dims for text-embedding-3-small)
CREATE TABLE documents (
  id        SERIAL PRIMARY KEY,
  content   TEXT NOT NULL,
  source    TEXT,
  embedding vector(1536)
);

-- Create an HNSW index for fast approximate nearest-neighbour search
CREATE INDEX ON documents USING hnsw (embedding vector_cosine_ops);

-- Insert a document with its embedding
INSERT INTO documents (content, source, embedding)
VALUES ('Refunds are processed within 5–7 business days.', 'policy.pdf', '[0.12, -0.04, ...]');

-- Find the 5 most similar documents to a query embedding
SELECT content, source,
       1 - (embedding <=> '[0.11, -0.03, ...]') AS similarity
FROM   documents
WHERE  source = 'policy.pdf'              -- metadata filter
ORDER  BY embedding <=> '[0.11, -0.03, ...]'   -- cosine distance
LIMIT  5;

<=> is cosine distance. Use <-> for L2 (Euclidean). Both operators use the HNSW index.

Pinecone - managed vector database

typescript
import { Pinecone } from '@pinecone-database/pinecone';

const pc = new Pinecone({ apiKey: process.env.PINECONE_API_KEY! });
const index = pc.index('my-docs');

// Upsert vectors with metadata
await index.upsert([
  {
    id: 'chunk-1',
    values: embeddingArray,       // number[] with 1536 elements
    metadata: { text: chunk, source: 'faq.pdf', page: 3 },
  },
]);

// Query: top-5 nearest neighbours, filtered by metadata
const result = await index.query({
  vector: queryEmbedding,
  topK: 5,
  includeMetadata: true,
  filter: { source: { $eq: 'faq.pdf' } },
});

const retrievedChunks = result.matches.map(m => m.metadata!.text as string);

Chroma - local/embedded vector store (great for dev/testing)

python
import chromadb

client = chromadb.Client()  # in-memory; use chromadb.PersistentClient(path) for disk

collection = client.create_collection('docs')

# Add documents (Chroma embeds them for you if you configure an embedding function)
collection.add(
    documents=['Our refund policy is 30 days.', 'Contact support at help@example.com'],
    ids=['doc-1', 'doc-2'],
    metadatas=[{'source': 'policy'}, {'source': 'contact'}]
)

# Query
results = collection.query(
    query_texts=['How do I get my money back?'],
    n_results=2
)
print(results['documents'])   # [['Our refund policy is 30 days.', ...]]

Pro Tip

If you already use PostgreSQL, start with **pgvector** - it means one less service to manage. For document counts under ~1M, pgvector with an HNSW index is fast enough for production. Only consider a dedicated vector database (Pinecone, Weaviate) when you need multi-tenant isolation, billion-scale search, or built-in replication that your Postgres setup cannot easily provide.