Skip to content

[python] Verify candidate-only scalar filters before vector top-k - #9999

Merged
JingsongLi merged 2 commits into
apache:masterfrom
TheR1sing3un:codex/vector-filter-exactness
Sep 20, 2026
Merged

JingsongLi merged 2 commits into
apache:masterfrom
TheR1sing3un:codex/vector-filter-exactness

Conversation

@TheR1sing3un

@TheR1sing3un TheR1sing3un commented Sep 20, 2026

Copy link
Copy Markdown
Member

Purpose

Prevent candidate-only scalar index answers from admitting non-matching rows into vector top-k. For example, with a BTree name index and an IVF vector index, name LIKE '%zeta%' can currently return the nearer alpha row instead of beta zeta. Filtering after top-k cannot recover the displaced match.

Carry scalar-result exactness through offsets, unions, intersections, coverage padding and conjunctions that drop an unsupported child. BTree prefix/substring answers are candidates; exact BTree equality/range results and exact bitmap string matches retain their existing path without a data recheck. When multiple indexes answer the same predicate, an exact reader makes their intersection exact; conjunctions of different predicates still require every child to be exact. This preserves exact BTree-plus-bitmap matches without a data recheck. Tracking the result also handles partially evaluable conditions on the same field, where contributing field IDs alone are insufficient.

Use the global-index.filter.refine-from-data table option introduced by #9953, with the same default of false. Inexact index candidates are excluded with a warning by default. When enabled, read the candidate filter columns at the pinned snapshot to build an exact include bitmap before ANN top-k. This read is streamed, applies deletion handling, and does not project candidate vectors. Completely unsupported scalar evaluations can also use this opt-in verification. Local/Ray and single/batch vector execution share this path.

Related to #9883. This change covers Python data-evolution vector search; full-text filtering remains unchanged.

Tests

  • New native-index and resource-lifetime tests: 53 passed, including all local/Ray, single/batch and full/fast combinations of the refinement option.
  • The same 53 new tests also passed on Ray 2.44 / NumPy 1.24 / Arrow 18 (primary environment: Ray 2.54 / NumPy 2.4 / Arrow 19).
  • Existing evaluator, union/sorted-index result and vector-filter regressions: 102 passed (155 total with the new tests).
  • Tests cover BTree prefix/substring candidates, exact BTree and bitmap fast paths, mixed BTree-plus-bitmap filtering with refinement disabled/enabled, reader-order independence and conservative predicate conjunctions, unsupported predicates on the same field, result-wrapper propagation, historical snapshots/tags and deletions, a commit before candidate verification, projected columns and stream cleanup.
  • Flake8, Python 3.6 syntax parsing and git diff --check passed for changed files. Native index tests used paimon-vindex 0.4.0.

Comment thread paimon-python/pypaimon/globalindex/global_index_result.py
@JingsongLi

Copy link
Copy Markdown
Contributor

+1

@JingsongLi
JingsongLi merged commit 663e598 into apache:master Sep 20, 2026
13 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants