This is a beta feature available in versions
0.25.0 and above. See How
Vector Search Works for background, and Indexing
Vectors to set up the index used in
these examples.ORDER BY <distance> ... LIMIT k query over a vector column in the ParadeDB index.
When one of ParadeDB’s search operators is present at the same level as the ORDER BY ... LIMIT, ParadeDB can accelerate the vector search query.
Unfiltered Nearest Neighbors
When you are not filtering, usepdb.all(), which matches every row:
Rails’
nearest adds the match-all predicate automatically when the relation
has no other search predicate, and defaults the metric to the one the index
was built with.<=> operator computes cosine distance, so this returns the five rows whose embeddings are nearest the query vector [1, 2, 3, 4, 5, 6, 7, 8].
This operator must match the distance metric used by the index. Otherwise, ParadeDB cannot use the index to order results and falls back to a slower brute force sort.
Filtered Nearest Neighbors
To search within a subset of rows, replacepdb.all() with a real predicate using any of the search operators.
For instance, the following query finds the nearest neighbors among results whose category contains the term footwear.
Note the lowercase footwear — the default tokenizer lowercases terms, so Footwear would not match.
Every column you filter on (e.g.
category above) must also be part of the
ParadeDB index. Filters on unindexed columns cannot be evaluated by the
ParadeDB index, forcing Postgres to recheck them afterward and eliminating the
benefit of combining vector search with
filtering.Deterministic Results
Tiebreaker columns require version
0.25.1 and above.LIMIT cuts through such a group, which of the tied rows come back can change between runs. Add a tiebreaker column after the distance to make the order stable:
DESC are both supported, and every tiebreaker column must be in the ParadeDB index to keep the Top K optimization.
Verifying Pushdown
UseEXPLAIN to confirm ParadeDB is accelerating the vector search. Look for a Custom Scan with an Exec Method of TopKScanExecState in the query plan:
Expected Response
Expected Response
category === 'footwear' filter was pushed down into the same index scan that performs the vector search. Without pushdown, the filter would run as a separate step after the nearest neighbors were fetched.
If you do not see a TopKScanExecState, the query fell back to a less efficient sort. This usually means the distance operator does not match how the vector column was indexed, the query is missing a LIMIT, or an ORDER BY or filter column is not indexed.