Search

Metadata filtering — structured conditions meet vector search.

Attach any structured attributes to your vectors and filter on them before or after scoring. Equality, range, set membership, and negation operators — all without a separate database.

Filter operators

Every condition you need, composable.

Equality

$eq / $ne

Exact match and negation on string, integer, or boolean attributes. {"source": {"$eq": "web"}}

Comparison

$gt / $gte / $lt / $lte

Range comparisons on numeric and date attributes. {"score": {"$gte": 0.8}}

Set

$in / $nin

Membership in or exclusion from a list. {"lang": {"$in": ["en", "de"]}}

Logical

$and / $or

Compose multiple conditions. {"$and": [{"lang": "en"}, {"score": {"$gte": 0.9}}]}

Existence

$exists

Match only vectors that have (or don't have) a particular attribute set. Useful for sparse attribute schemas.

Performance

Pre-filter before HNSW

Filters reduce the candidate set before HNSW traversal runs — improving both precision and query latency when the filter is selective.

By the numbers

Precision retrieval with zero compromise.

Any

attribute filterable

<1ms

filter overhead

AND/OR/NOT

logical operators

2

filter modes (pre/post)

FAQ

Common questions

Does filtering happen before or after vector search?

Both modes are available. Pre-filter (default for narrow conditions) applies before HNSW traversal. Post-filter applies after retrieval, which is faster for broad conditions.

What data types can I filter on?

String (exact, prefix, contains), number (eq, lt, gt, between), boolean, and array membership. Nested JSON attributes are supported.

How many filter conditions can I combine?

No hard limit. Combine conditions with AND, OR, and NOT operators. Deeply nested filter trees are supported.

Does heavy filtering reduce recall?

Pre-filter mode can reduce recall when the filter is very selective. Switch to post-filter mode or increase efSearch to over-retrieve before filtering in those cases.

Filter on any attribute without a separate database.