Skip to content

Filtered queries can return fewer than topK results vs Upstash (over-fetch-then-filter-in-JS) #4

Description

@Coriou

Surfaced by the 2026-06-29 maintenance audit (PR #2). Documented as a "v1" design choice in CLAUDE.md, but it's a real, observable divergence from Upstash on the dense surface up-vector claims to fully support.

Problem

In src/routes/query.ts (~lines 97-100), when a filter is present the server fetches min(topK*3, 1000) nearest-by-vector candidates from RediSearch, then applies the metadata filter in JS and trims to topK. Upstash applies the filter inside the index and returns up to topK matching results regardless of scan depth.

Consequences:

  • For a selective filter (say 5% match rate), up-vector returns ~0.05 × 3 × topK results instead of topK.
  • For topK ≥ 334 (any topK*3 > 1000) there is effectively no over-fetch headroom.

Suggested direction

Push filters into RediSearch: index metadata as TAG/NUMERIC schema fields and translate the filter AST into an FT.SEARCH filter expression. Alternatively, loop/deepen the KNN fetch until topK matches are found or the namespace is exhausted. Needs a design pass (the filter grammar is rich — GLOB/IN/CONTAINS/HAS FIELD/AND/OR/NOT — and not all map cleanly to RediSearch).

Acceptance criteria

  • A selective filter returns up to topK matching results, matching Upstash semantics, including for large topK.
  • The full filter operator set (tests/unit/filter.test.ts) remains supported end-to-end.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions