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.
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.
Precision retrieval with zero compromise.
Any
attribute filterable
<1ms
filter overhead
AND/OR/NOT
logical operators
2
filter modes (pre/post)
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.