0Pricing
AI Engineering Academy · Aula

pgvector: embeddings no PostgreSQL

Ative a extensão pgvector no PostgreSQL, crie uma tabela com uma coluna vetorial, insira embeddings e execute consultas de vizinhos mais próximos usando o operador de distância de cosseno .

pgvector: embeddings no PostgreSQL é uma aula grátis de AI Engineering Academy no CoddyKit. Esta é a aula 3 de 4. Você pode ler a aula completa abaixo gratuitamente — depois pratica ao vivo no navegador com um editor de código integrado e um tutor de IA 24/7. Faz parte do caminho de aprendizado de AI Engineering Academy, e seu progresso é sincronizado entre a web e o app CoddyKit. O curso de AI Engineering Academy inclui 4 aulas no total.

Partes desta aula ainda não foram traduzidas e aparecem em inglês.

pgvector: Vector Search in PostgreSQL

pgvector is an open-source PostgreSQL extension that adds a vector data type and similarity search operators. It lets you store embeddings alongside your regular application data in the same database you already operate, avoiding a separate vector store.

This is ideal for teams that already use PostgreSQL and want to add semantic search without introducing a new infrastructure dependency.

Enabling the pgvector Extension

Install pgvector from the official repository or use a managed PostgreSQL provider that pre-installs it (Supabase, Neon, AWS RDS, Render). Then enable it in your database with a single SQL command — no restart required.

-- Run this once per database to enable the extension
CREATE EXTENSION IF NOT EXISTS vector;

-- Verify it's installed
SELECT extname, extversion
FROM pg_extension
WHERE extname = 'vector';
-- Returns: vector | 0.7.0 (or similar)

Creating a Table with a Vector Column

Add a vector column by specifying vector(n) where n is the embedding dimension. You can combine it with regular PostgreSQL columns for metadata — this lets you filter by user_id, created_at, or any other field using standard SQL WHERE clauses.

CREATE TABLE documents (
    id          BIGSERIAL PRIMARY KEY,
    content     TEXT NOT NULL,
    category    TEXT,
    created_at  TIMESTAMPTZ DEFAULT NOW(),
    embedding   vector(1536)   -- must match your model dimension
);

-- Index on category for fast metadata filtering
CREATE INDEX ON documents (category);

SELECT column_name, data_type
FROM information_schema.columns
WHERE table_name = 'documents';

Inserting Embeddings from Python

Use the psycopg2 or asyncpg driver to insert rows with embeddings. Convert the Python list of floats to a string in the format '[0.1, 0.2, ...]' which pgvector parses correctly. The pgvector Python package provides a register_vector helper to handle this automatically.

import psycopg2
from pgvector.psycopg2 import register_vector
from openai import OpenAI

conn = psycopg2.connect('postgresql://user:pass@localhost/mydb')
register_vector(conn)
cur = conn.cursor()

client = OpenAI()

document = 'pgvector adds vector search to PostgreSQL.'
resp = client.embeddings.create(model='text-embedding-3-small', input=document)
embedding = resp.data[0].embedding

cur.execute(
    'INSERT INTO documents (content, category, embedding) VALUES (%s, %s, %s)',
    (document, 'database', embedding)
)
conn.commit()
print('Inserted document with embedding')

Cosine Similarity with the <=> Operator

pgvector adds three distance operators:

  • <=> — cosine distance (1 - cosine_similarity)
  • <-> — Euclidean (L2) distance
  • <#> — negative inner product (use for dot product similarity)

For text embeddings, use <=> (cosine distance). ORDER BY distance ASC returns the most similar documents first.

-- Find top 5 documents most similar to a query embedding
-- Replace '[0.1, 0.2, ...]' with the actual query vector
SELECT
    id,
    content,
    category,
    1 - (embedding <=> '[0.1, 0.2, 0.3]'::vector) AS cosine_similarity
FROM documents
ORDER BY embedding <=> '[0.1, 0.2, 0.3]'::vector
LIMIT 5;

Combining Vector Search with SQL Filters

One of pgvector's biggest advantages is that you can combine ANN search with standard SQL WHERE clauses. This enables metadata filtering natively without any special syntax — just write SQL.

-- Semantic search filtered to the 'database' category
-- and only recent documents
SELECT
    id,
    content,
    1 - (embedding <=> %s::vector) AS similarity
FROM documents
WHERE
    category = 'database'
    AND created_at > NOW() - INTERVAL '30 days'
ORDER BY embedding <=> %s::vector
LIMIT 5;

-- In Python with psycopg2:
# cur.execute(sql, (query_embedding, query_embedding))

Creating an HNSW Index for Speed

Without an index, pgvector does an exact scan of every row — fine for under 10,000 rows but slow at scale. Create an HNSW index for approximate nearest neighbor search. The m (connections per node) and ef_construction (build-time search width) parameters trade index size and build time for recall accuracy.

-- Create an HNSW index for cosine distance queries
CREATE INDEX ON documents
USING hnsw (embedding vector_cosine_ops)
WITH (m = 16, ef_construction = 64);

-- At query time, control recall vs speed:
SET hnsw.ef_search = 40;  -- higher = better recall, slower

-- Verify the index is being used:
EXPLAIN SELECT * FROM documents
ORDER BY embedding <=> '[0.1]'::vector(1)
LIMIT 5;

IVFFlat Index: Alternative to HNSW

The IVFFlat index type clusters vectors into lists buckets and searches only the nearest probes buckets at query time. It builds faster than HNSW and uses less memory, but has slightly lower recall for the same speed.

Rule of thumb: use IVFFlat when you need faster index builds during frequent re-indexing; use HNSW for stable corpora that need maximum query speed.

-- IVFFlat index: good for large, infrequently updated corpora
-- lists ≈ sqrt(n) where n is the number of vectors
CREATE INDEX ON documents
USING ivfflat (embedding vector_cosine_ops)
WITH (lists = 100);

-- At query time, probes controls recall vs speed:
SET ivfflat.probes = 10;  -- check 10 of 100 clusters

Full Python Query Example

Here is a complete Python function that takes a user query, embeds it, runs a pgvector similarity search with metadata filtering, and returns the top-k results as a list of dicts.

import psycopg2
from pgvector.psycopg2 import register_vector
from openai import OpenAI

conn = psycopg2.connect('postgresql://user:pass@localhost/mydb')
register_vector(conn)
client = OpenAI()

def semantic_search(query, category=None, top_k=5):
    resp = client.embeddings.create(model='text-embedding-3-small', input=query)
    q_vec = resp.data[0].embedding

    sql = '''
        SELECT content,
               1 - (embedding <=> %s::vector) AS similarity
        FROM documents
        {where}
        ORDER BY embedding <=> %s::vector
        LIMIT %s
    '''
    where = 'WHERE category = %s' if category else ''
    params = [q_vec, q_vec, top_k] if not category else [q_vec, category, q_vec, top_k]
    cur = conn.cursor()
    cur.execute(sql.format(where=where), params)
    return [{'text': r[0], 'score': r[1]} for r in cur.fetchall()]

pgvector vs Pinecone Trade-offs

Comparing pgvector and Pinecone:

  • pgvector: self-hosted, no extra cost, perfect SQL integration, scales to ~5M vectors well, requires DBA knowledge for tuning
  • Pinecone: fully managed, massive scale (billions of vectors), specialized filtering, more expensive, separate service to operate

Choose pgvector when you already run PostgreSQL and your corpus is under a few million documents. Choose Pinecone for massive scale or when avoiding ops burden is worth the cost.

Using pgvector with Supabase

Supabase is a hosted PostgreSQL service with pgvector pre-installed. It provides a Python client (supabase-py) and a REST API for vector queries, making it the easiest way to get a production pgvector setup without managing a database server yourself.

from supabase import create_client
import os

url = os.environ['SUPABASE_URL']
key = os.environ['SUPABASE_SERVICE_KEY']
supabase = create_client(url, key)

# Insert a document with embedding
supabase.table('documents').insert({
    'content': 'Supabase hosts PostgreSQL with pgvector.',
    'embedding': embedding   # list of 1536 floats
}).execute()

# Vector similarity search via RPC (Supabase edge function)
# result = supabase.rpc('match_documents', {'query_embedding': q_vec, 'match_count': 5}).execute()

Quick Check

Test your understanding of AI Engineering concepts from this lesson.

Lesson Recap

In this lesson you learned: pgvector adds a vector column type and cosine/Euclidean distance operators to PostgreSQL, HNSW indexes enable fast approximate nearest neighbor search at scale, and standard SQL WHERE clauses provide metadata filtering without any special syntax. Next up we compare all the major vector store options to help you choose the right one for your project.

Perguntas Frequentes

A aula “pgvector: embeddings no PostgreSQL” é grátis?

Sim — o texto completo de “pgvector: embeddings no PostgreSQL” é grátis para ler aqui na web. Para praticá-la interativamente (um editor de código integrado e um tutor de IA 24/7) e desbloquear o restante do curso de AI Engineering Academy, atualize para CoddyKit PRO. O curso de AI Engineering Academy inclui 4 aulas no total.

O que vou aprender em “pgvector: embeddings no PostgreSQL”?

Ative a extensão pgvector no PostgreSQL, crie uma tabela com uma coluna vetorial, insira embeddings e execute consultas de vizinhos mais próximos usando o operador de distância de cosseno . Você pratica AI Engineering Academy com código prático que executa diretamente no navegador, e um tutor de IA 24/7 responde suas dúvidas enquanto trabalha na aula.

Preciso ter experiência prévia para começar AI Engineering Academy?

Nenhuma experiência prévia é necessária. AI Engineering Academy no CoddyKit é estruturado para alunos iniciantes até avançados, então você pode começar aqui ou desde o início e aprender no seu ritmo. Esta é a aula 3 de 4.

Quanto tempo leva a aula “pgvector: embeddings no PostgreSQL”?

A maioria das aulas CoddyKit leva cerca de 5–10 minutos. Cada uma é compacta e interativa, então você faz progresso constante e retoma exatamente de onde parou entre web e app.

Posso escrever e executar código nesta aula de AI Engineering Academy?

Sim. Cada aula de AI Engineering Academy inclui um editor de código integrado, então você escreve e executa código real direto no navegador e recebe feedback de IA instantaneamente — nenhuma configuração local necessária.

Todas as aulas deste curso

  1. Por que você precisa de um banco de dados vetorial
  2. Primeiros passos com Pinecone
  3. pgvector: embeddings no PostgreSQL
  4. Escolhendo e avaliando armazenamentos vetoriais
← Voltar para AI Engineering Academy