Skip to main content
Version: Next
pgvector_searchINPUTBUFFERPROCESSOROUTPUT

pgvector Search

The pgvector_search processor runs one nearest-neighbor SELECT per row against a PostgreSQL table with the pgvector extension and appends the matches as a JSON array text column. The table shape mirrors what the pgvector output writes — (id, embedding vector(n), payload jsonb) — so ingestion and retrieval work on the same table out of the box.

Configuration​

FieldTypeRequiredDefaultDescription
typestringyes—pgvector_search
urlstringyes—Postgres connection string. Supports secret references.
tablestringyes—Table to search (must already exist).
vector_fieldstringnoembeddingBatch column holding the query vector (FixedSizeList/List of Float32).
target_fieldstringnomatchesName of the appended matches column.
id_columnstringnoidTable column returned as the match id (as text).
vector_columnstringnoembeddingTable column holding the stored vectors.
payload_columnstringnopayloadjsonb column included in each match as a payload object. Set to "" to disable.
metricstringnocosineDistance operator: cosine (<=>), l2 (<->), inner_product (<#>).
top_kintegerno5Number of neighbors per row.
concurrencyintegerno4Maximum in-flight queries; results are always filled back in row order.
max_connectionsintegerno4Connection pool size.
timeout_msintegerno30000Pool acquire timeout.

Distance semantics​

distance is the raw pgvector operator result, nearest-first via ORDER BY ... <op> $1:

metricoperatordistance meaning
cosine<=>cosine distance, 0 = identical direction, range [0, 2]
l2<->Euclidean distance, 0 = identical
inner_product<#>negative inner product (smaller = more similar)

Each match object carries id (as text), distance, and payload (the parsed jsonb object) — the JSON text feeds directly into an LLM processor prompt or downstream JSON tooling.

note

Failures (null/empty query vector, SQL errors) fail the batch into error_output. The processor does not retry. The connection pool is created lazily, so building the component never touches the network.

Example​

- type: "pgvector_search"
url: "postgres://postgres:${env:PG_PASSWORD:-}@localhost:5432/vectors"
table: "documents"
metric: "cosine"
top_k: 5

Complete RAG Query Pipeline​

logging:
level: info

streams:
- id: pgvector-rag-query
input:
type: memory
pipeline:
thread_num: 4
processors:
- type: json_to_arrow
- type: embedding
api_base: "http://localhost:9997/v1"
model: "text-embedding-3-small"
api_key: "${env:OPENAI_API_KEY:-}"
field: "text"
- type: pgvector_search
url: "postgres://postgres:${env:PG_PASSWORD:-}@localhost:5432/vectors"
table: "documents"
metric: "cosine"
top_k: 5
output:
type: stdout

Testing against a live database​

The workspace test suite contains an ignored integration test that needs a real Postgres with the pgvector extension:

docker run --rm -p 5432:5432 -e POSTGRES_PASSWORD=postgres pgvector/pgvector:pg16
cargo test -p arkflow-plugin --lib processor::pgvector_search -- --ignored