Skip to Content
v2ConceptsFiltering

Filtering

Use filters to restrict search results to objects that match specific conditions. All filter conditions are combined with logical AND: an object must satisfy every condition to be returned. Filters are evaluated server-side before ranking, so objects that fail the filter never enter the result set.

Operators

OperatorDescriptionExample
$eqExact match{“status”: {“$eq”: “published”}}
$inMatch any value in a list{“tags”: {“$in”: [“ai”, “ml”]}}
$rangeNumeric range (inclusive on both ends){“score”: {“$range”: [70, 95]}}
$gt / $gteGreater than / or equal{“price”: {“$gt”: 50}}
$lt / $lteLess than / or equal{“price”: {“$lte”: 100}}
# $eq — exact match res = collection.search( fields={"embedding": {"query": [...], "limit": 5}}, filter=[{"category": {"$eq": "tech"}}], ) # $in — match any value in a list res = collection.search( fields={"embedding": {"query": [...], "limit": 5}}, filter=[{"tags": {"$in": ["ai", "ml", "nlp"]}}], ) # $range — numeric range (inclusive) res = collection.search( fields={"embedding": {"query": [...], "limit": 5}}, filter=[{"score": {"$range": [80, 100]}}], ) # combined — all conditions must be satisfied (logical AND) res = collection.search( fields={"embedding": {"query": [...], "limit": 5}}, filter=[ {"category": {"$eq": "tech"}}, {"score": {"$range": [80, 100]}}, ], )

Notes:

  • Operators are case-sensitive
  • Multiple conditions must all be satisfied (logical AND)
  • Only keys declared in an object’s filter at upsert time can be used in a filter expression

Filter Tuning

When using filtered search, two optional parameters let you tune the trade-off between search speed and recall.

Prefilter Cardinality Threshold

Controls when the search strategy switches from HNSW filtered search to brute-force prefiltering.

When very few objects match your filter, HNSW may struggle to find enough valid candidates through graph traversal. In that case, scanning the matched subset directly (prefiltering) is faster and more accurate.

  • Default: 10,000
  • Valid range: 1,0001,000,000
  • Raising the threshold → prefiltering kicks in more often (favors exhaustive scan)
  • Lowering the threshold → HNSW graph search is used more (favors speed on large datasets)

Filter Boost Percentage

When using HNSW filtered search, candidates explored during graph traversal that fail the filter are discarded, which can leave you with fewer results than limit. This parameter expands the internal candidate pool before filtering is applied to compensate.

  • Default: 0 (no boost)
  • Higher values explore more paths (more thorough, slightly slower)
res = collection.search( fields={"embedding": {"query": [...], "limit": 10}}, filter=[{"category": {"$eq": "rare"}}], prefilter_cardinality_threshold=5000, filter_boost_percentage=25, )

Start with the defaults. If filtered searches return fewer results than expected, increase the filter boost percentage. If filtered searches are slow on selective filters, lower the cardinality threshold. See the Filter Tuning Guide for worked examples.

Updating Filters

You can update the filter tags of existing objects by providing their IDs and a new filter object.

ParameterRequiredDescription
idYesID of the object to update
filterYesNew filter object (replaces the existing filters entirely)
collection.update_filters([ {"id": "doc1", "filter": {"category": "science", "year": 2024}}, {"id": "doc2", "filter": {"category": "tech"}}, ])

Filter updates are destructive replacements. Any filter keys not included in the new filter object will be removed from the object. There is no partial-merge option.