ann_router.backends.pgvector_backend module

pgvector backend — vector search inside an existing PostgreSQL.

pgvector’s niche is persistence + metadata filters when a Postgres is already in place: you keep vectors next to your relational data and filter with plain SQL WHERE clauses, backed by an HNSW index on the vector column. The router picks it (over Qdrant) when the criteria say “a database is already there”, because reusing it beats standing up a second datastore. Unlike every other backend this one needs a live server, so it is unavailable unless a DSN is supplied — absence is a clean skip, never a crash.

Consumes: pgvector + psycopg (optional, pip install 'ann-router[pgvector]') and a reachable PostgreSQL with the vector extension. Produces: PgVectorIndex.

Author: Warith Harchaoui <warith.harchaoui@deraison.ai>

class ann_router.backends.pgvector_backend.PgVectorIndex(dim, metric='cosine', **kwargs)[source]

Bases: ANNIndex

A single vectors table in PostgreSQL, indexed with pgvector HNSW.

Requires a DSN (dsn= kwarg or the ANN_ROUTER_PG_DSN env var). Points live in a (id bigint, embedding vector(dim), payload jsonb) table so the SQL WHERE path can filter on payload.

Parameters:
  • dim (int) – Embedding dimensionality.

  • metric ({"cosine", "l2", "ip"}, optional) – Distance metric. Defaults to "cosine".

  • dsn (str, optional) – PostgreSQL connection string. Falls back to ANN_ROUTER_PG_DSN.

  • table (str, optional) – Table name. Defaults to "ann_router".

  • kwargs (object)

Examples

>>> PgVectorIndex.capabilities().persistent
True
add(vectors)[source]

Append vectors with ids continuing past the current max.

Parameters:

vectors (numpy.ndarray) – Shape (m, dim).

Return type:

None

add_with_ids(vectors, ids)[source]

Append vectors with explicit ids.

Parameters:
  • vectors (numpy.ndarray) – Shape (m, dim).

  • ids (numpy.ndarray) – Shape (m,) integer ids.

Return type:

None

build(vectors, ids=None, payloads=None)[source]

(Re)create the table, insert the corpus, and build the HNSW index.

Parameters:
  • vectors (numpy.ndarray) – Shape (n, dim).

  • ids (numpy.ndarray, optional) – Shape (n,); defaults to range(n).

  • payloads (list of dict, optional) – One JSON-serialisable payload per row, aligned with vectors.

Returns:

self.

Return type:

PgVectorIndex

classmethod capabilities()[source]

Return the pgvector capability descriptor (persistent + filterable).

Return type:

Capabilities

classmethod is_available()[source]

Return True if psycopg + pgvector import (a live DSN is still needed).

Examples

>>> isinstance(PgVectorIndex.is_available(), bool)
True
Return type:

bool

load(path)[source]

Reconnect to the existing table (path may override the DSN).

Parameters:

path (str) – A DSN to reconnect with, or falsy to reuse the constructor’s DSN.

Returns:

self, reconnected.

Return type:

PgVectorIndex

remove(ids)[source]

Delete rows by id.

Parameters:

ids (numpy.ndarray) – Shape (m,) integer ids to drop.

Return type:

None

save(path)[source]

No-op — the table lives in PostgreSQL and is already durable.

Parameters:

path (str) – Unused — accepted only to satisfy the shared interface.

Return type:

None

Notes

Persistence is the database’s job; there is nothing to serialise. Use the same DSN + table to load() the index in another process.

search(queries, k)[source]

Return approximate top-k neighbours per query (no filter).

Parameters:
  • queries (numpy.ndarray) – Shape (q, dim).

  • k (int) – Neighbours per query.

Returns:

  • ids (numpy.ndarray) – Shape (q, k) neighbour ids.

  • distances (numpy.ndarray) – Shape (q, k) distances under the metric operator.

Return type:

tuple[ndarray, ndarray]

search_filter(queries, k, where=None)[source]

Return top-k neighbours, optionally filtered by a payload clause.

Parameters:
  • queries (numpy.ndarray) – Shape (q, dim).

  • k (int) – Neighbours per query.

  • where (dict, optional) – {field: value} equality constraints matched against the JSONB payload column. None searches the whole table.

Returns:

  • ids (numpy.ndarray) – Shape (q, k) (-1 pads short rows).

  • distances (numpy.ndarray) – Shape (q, k) distances under the metric operator.

Return type:

tuple[ndarray, ndarray]