How do you store and search vector embeddings in PostgreSQL using pgvector?

Asked 22 days ago Updated 5 hours ago 108 views

0

Retrieval-Augmented Generation (RAG) relies heavily on vector databases to match semantically similar items. Rather than deploying specialized standalone vector engines, developers can turn existing relational databases into hybrid search engines using the pgvector extension.

1 Answer


0

With pgvector, you can keep embeddings alongside your regular PostgreSQL data and query for the nearest matches using SQL. The extension provides a vector data type and distance operators; your application still needs to generate the embeddings, usually with an embedding model.

Enable pgvector and create a table

Install pgvector for your PostgreSQL setup, then enable it in the database. Set the column size to match the number of values returned by your embedding model. The three-dimensional vectors below are just a small example; real models commonly produce hundreds or thousands of dimensions.

CREATE EXTENSION IF NOT EXISTS vector;

CREATE TABLE documents (
    id bigserial PRIMARY KEY,
    content text NOT NULL,
    embedding vector(3) -- Use your model's actual embedding dimension.
);

INSERT INTO documents (content, embedding)
VALUES
    ('A guide to growing tomatoes', '[0.10, 0.80, 0.20]'),
    ('How to care for houseplants', '[0.15, 0.75, 0.25]'),
    ('A history of electric cars', '[0.90, 0.10, 0.30]');

Find similar rows

Pass the query text through the same embedding model used for the stored content, then provide its vector to PostgreSQL. The <=> operator calculates cosine distance; smaller values mean closer matches.

SELECT
    id,
    content,
    embedding <=> '[0.12, 0.78, 0.22]' AS distance
FROM documents
ORDER BY embedding <=> '[0.12, 0.78, 0.22]'
LIMIT 5;

For a small table, PostgreSQL can calculate distances directly. For larger collections, add an approximate nearest-neighbor index. An HNSW index configured with cosine distance looks like this:

CREATE INDEX documents_embedding_hnsw
ON documents
USING hnsw (embedding vector_cosine_ops);

Other common choices include <-> for Euclidean distance and <#> for negative inner product. Choose the operator and index operator class to match how your embeddings are intended to be compared. Approximate indexes trade some recall for speed, so test results on your data; filtered searches may also return fewer matches than expected when filters are applied after approximate retrieval.

Keep the model and vector dimensions consistent between stored rows and query embeddings. If you change embedding models, regenerate the stored vectors rather than comparing vectors from different models.

Write Your Answer