Database / pgvector basics Interview Questions
How do you use the inner product operator <#> with pgvector and when is it appropriate?
The <#> operator computes the negative inner product (dot product) between two vectors. It is most useful with normalised vectors (unit vectors where magnitude = 1), in which case it is mathematically equivalent to cosine similarity but computed faster.
-- <#> returns the NEGATIVE inner product -- For unit vectors: inner_product = cosine_similarity -- ORDER BY <#> ASC = most similar first (most negative = highest similarity) -- Inner product similarity search: SELECT id, content, -(embedding <#> '[0.1,0.2,0.3]') AS inner_product_similarity FROM documents ORDER BY embedding <#> '[0.1,0.2,0.3]' -- ASC order = most similar LIMIT 5; -- NOTE: negate in SELECT for display, but use the raw expression in ORDER BY -- Why negative? PostgreSQL indexes only support ASC scans -- High inner product = more similar, but ASC would put low values first -- Solution: return the NEGATIVE so ASC scan gives most similar first -- When inner product == cosine similarity: -- When all vectors are unit-normalised (L2 norm = 1.0) -- OpenAI text-embedding-3-small/large outputs ARE unit-normalised -- So for OpenAI embeddings, <#> and <=> produce equivalent RANKINGS -- Verify your vectors are normalised: SELECT id, l2_norm(embedding) AS norm FROM documents LIMIT 5; -- Should return values very close to 1.0 for normalised vectors -- HNSW index for inner product: CREATE INDEX ON documents USING hnsw (embedding vector_ip_ops); -- IVFFlat index for inner product: CREATE INDEX ON documents USING ivfflat (embedding vector_ip_ops) WITH (lists = 100);
More Related questions...