OriginChain docs
examples · vector · 7 / 7

7. Filtered top-k

← Vector examples
what this does

Pass a filter object to restrict the search to vectors whose stored metadata matches every key. The example above only ranks vectors where category == "shoes". See put-metadata for how to attach the metadata in the first place.

The filter is applied during the search, not after - so a selective filter (say, 2% of the table) stays fast and still returns k hits.

when to use it
  • Multi-tenant search where tenant_id must match.
  • Faceted search (category, brand, language, region).
  • Soft-delete: filter on deleted: false at query time instead of rebuilding the index.
the request
POST /v1/tenants/:t/vector/:table/topk
curl -X POST "https://$OC_HOST/v1/tenants/$OC_TENANT/vector/shop.products/topk" \
  -H "Authorization: Bearer $OC_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "query":  [0.0124, -0.0883, 0.0451, /* ... 768 floats ... */],
    "k":      10,
    "dim":    768,
    "metric": "cosine",
    "filter": { "category": "shoes" }
  }'
what you get back
{
  "hits": [
    { "id": "sku-9281", "score": 0.9421 },
    { "id": "sku-1144", "score": 0.9187 }
    /* ... only rows whose category == "shoes" ... */
  ]
}

Same shape as an unfiltered topk. If fewer than k rows match the filter, you get back what exists - no padding.

filter rules
RuleNotes
Equality onlyNo $gt, $in, range, or regex. Just key: value pairs.
Multiple keys are AND{ "category": "shoes", "in_stock": true } means both must match.
Exact match, case-sensitive"Shoes" does not match "shoes". Normalise on insert.
Strings, numbers, booleansNested objects and arrays are not filterable. Flatten at put time.
common mistakes
  • Range filters. Not supported. If you need price < 100, bucket the price at insert time (price_band: "under_100") and filter on the bucket.
  • Case-mismatched values. Filter values must match exactly. "shoes" and "Shoes" are different. Lowercase on the way in.
  • Filtering on a field that was never stored. The filter doesn't error - it just matches nothing, and you get an empty hits array. Double-check the metadata was set when you called put.