Skip to content

fix(index): sort search top-k results by relevance when not truncating#614

Open
XiaoHongbo-Hope wants to merge 3 commits into
apache:mainfrom
XiaoHongbo-Hope:fix-vector-search-topk-ordering
Open

fix(index): sort search top-k results by relevance when not truncating#614
XiaoHongbo-Hope wants to merge 3 commits into
apache:mainfrom
XiaoHongbo-Hope:fix-vector-search-topk-ordering

Conversation

@XiaoHongbo-Hope

@XiaoHongbo-Hope XiaoHongbo-Hope commented Jul 26, 2026

Copy link
Copy Markdown
Contributor

Companion PR: #613

SearchResult::top_k only sorted by score on the truncation path (candidates > k).
When k >= candidate count, it returned rows in the unordered scored-map / insertion
order instead of by relevance.

This went unnoticed because the row order was previously discarded downstream (row-range
scans re-read in file order); but consumers that honor the row order — e.g. the
DataFusion vector_search scan (#613) — then get unranked results whenever
limit >= number of matched rows. The same bug existed in full_text's separate
SearchResult::top_k. (hybrid_search re-ranks its results itself, so it is not
affected.)

Fix: sort the no-truncation path by relevance rank in both the vector and full_text
SearchResult::top_k, with a consistent NaN-safe comparator and smaller-row-id
tie-break; update the unit tests that asserted the old insertion-order behavior.

`SearchResult::top_k` only sorted results by score on the truncation path
(candidates > k). When `k >= candidate count`, it returned rows in the
unordered scored-map / insertion order instead of by relevance. Because the
row order was previously discarded downstream (row-range scans re-read in
file order), this went unnoticed — but consumers that honor the row order
(e.g. the DataFusion `vector_search` scan) then get unranked results whenever
`limit >= number of matched rows`. This affects `vector_search`,
`full_text_search`, and `hybrid_search`.

Sort the no-truncation branch by relevance rank too, and update the unit
tests that asserted the old insertion-order behavior.
@XiaoHongbo-Hope
XiaoHongbo-Hope force-pushed the fix-vector-search-topk-ordering branch from 4c1418e to 5f605ba Compare July 26, 2026 14:02
full_text's SearchResult::top_k had the same bug as the vector one: when
`k >= candidate count` it returned rows in input/shard order instead of by
relevance score. Drop the no-truncation early-return so both paths sort
best-first, and update the test that asserted the old order.
Use total_cmp (NaN-safe) and an explicit smaller-row-id tie-break in
full_text's top_k, matching vector_search's ordering. This keeps the result
deterministic regardless of input/shard order rather than relying on a stable
sort over the input sequence.
@XiaoHongbo-Hope XiaoHongbo-Hope changed the title fix(index): sort vector search top-k results when not truncating fix(index): sort search top-k results by relevance when not truncating Jul 26, 2026
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.

1 participant