Skip to content

fix: apply score_threshold filtering after fusion queries in local mode#1138

Merged
joein merged 2 commits intoqdrant:devfrom
cbcoutinho:fix/fusion-score-threshold-dev
Dec 16, 2025
Merged

fix: apply score_threshold filtering after fusion queries in local mode#1138
joein merged 2 commits intoqdrant:devfrom
cbcoutinho:fix/fusion-score-threshold-dev

Conversation

@cbcoutinho
Copy link
Copy Markdown
Contributor

Summary

  • Apply score_threshold filtering after fusion queries in local mode to match server behavior
  • Simplify and improve score threshold tests
  • Add formula threshold test

This PR reimplements the fix from the main branch onto the dev branch.

Related: Closes original PR targeting main branch


This PR was generated with the help of AI, and reviewed by a Human

cbcoutinho and others added 2 commits December 16, 2025 13:14
The local/memory client was not applying score_threshold filtering after
RRF and DBSF fusion operations. This caused query_points with prefetch
and fusion queries to return results below the specified score_threshold.

This fix adds score_threshold filtering after fusion results are computed,
matching the behavior of the remote Qdrant server.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@netlify
Copy link
Copy Markdown

netlify bot commented Dec 16, 2025

Deploy Preview for poetic-froyo-8baba7 ready!

Name Link
🔨 Latest commit fb72e6d
🔍 Latest deploy log https://app.netlify.com/projects/poetic-froyo-8baba7/deploys/69414dba19704500084186f7
😎 Deploy Preview https://deploy-preview-1138--poetic-froyo-8baba7.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Dec 16, 2025

📝 Walkthrough

Walkthrough

This pull request implements score_threshold filtering for fusion queries (RRF and DBSF) in the Qdrant client. The primary change adds a score_threshold filter in the _merge_sources method of local_collection.py, which prunes fused results before payload and vector retrieval. Supporting changes include two new test helper methods in the congruence test suite that validate score-thresholded fusion query variants, and two new integration tests that verify score_threshold behavior for both RRF and DBSF fusion types.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

  • Local collection logic: The core change in _merge_sources introduces conditional score_threshold filtering after fusion computation. Requires verification that pruning occurs at the correct stage and that subsequent offset/pagination handling accounts for filtered results.
  • Test coverage: New helper methods add test variants; new integration tests cover both RRF and DBSF with explicit threshold values. These additions are straightforward but multiple files are touched.

Possibly related issues

Suggested reviewers

  • coszio

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 20.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title 'fix: apply score_threshold filtering after fusion queries in local mode' directly and clearly describes the main change: implementing score_threshold filtering after fusion queries in local mode.
Description check ✅ Passed The description is directly related to the changeset, explaining the purpose of applying score_threshold filtering after fusion queries, simplifying tests, and adding formula threshold tests.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (1)
tests/congruence_tests/test_query.py (1)

431-444: Clarify the TODO comment for future maintenance.

The TODO indicates that score_threshold is not applied in formula queries in core. This test verifies that local mode matches this behavior (i.e., both should return the same unfiltered results). Consider rewording to make the intent clearer:

-            score_threshold=1.0,  # todo: score threshold is not applied in formula queries in core
+            score_threshold=1.0,  # Note: score_threshold is intentionally NOT applied in formula queries (matches core behavior)

This distinguishes it from a "to-do" item and clarifies it's documenting expected behavior rather than a bug to fix.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 144f4ea and fb72e6d.

📒 Files selected for processing (3)
  • qdrant_client/local/local_collection.py (1 hunks)
  • tests/congruence_tests/test_query.py (2 hunks)
  • tests/test_in_memory.py (1 hunks)
🧰 Additional context used
🧬 Code graph analysis (2)
tests/test_in_memory.py (1)
qdrant_client/http/models/models.py (2)
  • FusionQuery (962-963)
  • Fusion (950-959)
tests/congruence_tests/test_query.py (3)
qdrant_client/http/models/models.py (6)
  • ScoredPoint (2510-2521)
  • Prefetch (2023-2047)
  • RrfQuery (2466-2467)
  • Rrf (2458-2463)
  • FormulaQuery (945-947)
  • MultExpression (1679-1680)
qdrant_client/async_qdrant_remote.py (1)
  • query_points (364-469)
qdrant_client/http/api/search_api.py (2)
  • query_points (550-565)
  • query_points (773-788)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: Redirect rules - poetic-froyo-8baba7
  • GitHub Check: Header rules - poetic-froyo-8baba7
  • GitHub Check: Pages changed - poetic-froyo-8baba7
🔇 Additional comments (5)
qdrant_client/local/local_collection.py (1)

826-839: LGTM! Score threshold filtering correctly applied after fusion.

The implementation correctly:

  1. Filters fused results by score >= score_threshold before payload/vector retrieval (efficient)
  2. Applies offset after filtering (correct order of operations)
  3. Excludes FormulaQuery from threshold filtering, matching server behavior
tests/test_in_memory.py (2)

123-208: Well-structured test for RRF score threshold filtering.

The test properly validates:

  • Baseline behavior without threshold (all 5 points returned)
  • Filtered behavior with threshold (only qualifying points)
  • Per-point score assertions for correctness

The docstring clearly documents expected RRF scores for the test data.


211-296: Good parallel test for DBSF fusion with score threshold.

Follows the same pattern as the RRF test with appropriate threshold value (1.0) for DBSF score distribution. This ensures both fusion algorithms are covered.

tests/congruence_tests/test_query.py (2)

416-429: Good congruence test for RRF fusion with score threshold.

The test validates that local mode matches remote behavior for RRF queries with score_threshold. The inline comment documenting expected results (3 results: 1.0, 0.5, 0.3̅) is helpful for debugging failures.


1333-1338: LGTM! Congruence tests added for both fusion score threshold variants.

The new test methods are properly integrated into test_dense_query_fusion, ensuring local-remote consistency for score-thresholded fusion queries.

@joein
Copy link
Copy Markdown
Member

joein commented Dec 16, 2025

@cbcoutinho thanks for addressing my comment and your contribution!

@joein joein self-requested a review December 16, 2025 15:10
@joein joein merged commit be22085 into qdrant:dev Dec 16, 2025
8 checks passed
joein added a commit that referenced this pull request Feb 19, 2026
…de (#1138)

* fix: apply score_threshold filtering after fusion queries in local mode

The local/memory client was not applying score_threshold filtering after
RRF and DBSF fusion operations. This caused query_points with prefetch
and fusion queries to return results below the specified score_threshold.

This fix adds score_threshold filtering after fusion results are computed,
matching the behavior of the remote Qdrant server.

* tests: simplify score threshold tests, add formula threshold test

---------

Co-authored-by: George Panchuk <george.panchuk@qdrant.tech>
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