Skip to content

[8.4] MOD-13885: Fix FT.HYBRID VSIM RANGE + FILTER returning zero results#8258

Merged
redisearch-backport-pull-request[bot] merged 1 commit into8.4from
backport-8205-to-8.4
Feb 3, 2026
Merged

[8.4] MOD-13885: Fix FT.HYBRID VSIM RANGE + FILTER returning zero results#8258
redisearch-backport-pull-request[bot] merged 1 commit into8.4from
backport-8205-to-8.4

Conversation

@redisearch-backport-pull-request
Copy link
Copy Markdown
Contributor

@redisearch-backport-pull-request redisearch-backport-pull-request Bot commented Feb 3, 2026

Description

Backport of #8205 to 8.4.

Describe the changes in the pull request

A clear and concise description of what the PR is solving, including:

  1. Current:
    When the document insertion order doesn't match the score order returned by the vector RANGE query, the query returns no results instead of the expected matches.

Root Cause

  • RANGE queries in FT.HYBRID are always combined with a filter (either explicit like @description:blue or implicit "*") via a PHRASE node in the AST.
  • The PHRASE node creates an intersection iterator that uses SkipTo operations to efficiently find documents existing in all child iterators.
  • SkipTo requires child iterators to be sorted by document ID.
  • The bug: RANGE queries were returning results sorted BY_SCORE (by vector distance). When the score order differs from the document ID order (which is determined by insertion order), the SkipTo operations fail to find matching documents because they assume sorted-by-ID iteration.
  1. Change:
    We implemented a conditional approach based on whether an explicit FILTER clause is provided:
  • RANGE + explicit FILTER → Use BY_ID ordering (required for intersection iterator compatibility)
  • RANGE without explicit FILTER → Use BY_SCORE ordering and skip filter integration so the vector node becomes the root directly
  1. Outcome:
  • FT.HYBRID VSIM RANGE + FILTER returns right results independent of docs ingestion order.
  • test_hybrid_vector_range_with_filter was failing if the docs were ingested in different order of the vector results, now it works independent of ingestion order.

Which additional issues this PR fixes

  1. MOD-13885
  2. #...

Main objects this PR modified

  1. ...

Mark if applicable

  • This PR introduces API changes
  • This PR introduces serialization changes

Release Notes

  • This PR requires release notes
  • This PR does not require release notes

If a release note is required (bug fix / new feature / enhancement), describe the user impact of this PR in the title.


Note

Medium Risk
Changes hybrid vector RANGE query planning/ordering and AST integration logic, which can affect correctness of filtered and unfiltered VSIM results. Risk is mitigated by expanded C++ and Python tests covering filtered/unfiltered RANGE across different document insertion orders.

Overview
Fixes FT.HYBRID VSIM RANGE queries returning wrong/empty results when combined with FILTER.

RANGE now uses BY_ID ordering only when an explicit FILTER is provided (so intersection/SkipTo works), while RANGE without an explicit filter keeps BY_SCORE ordering by skipping filter integration and making the vector node the AST root.

Also avoids parsing the implicit wildcard query ("*") when filter integration is skipped, and updates/extends C++ and Python tests to validate ordering and correctness regardless of document ingestion order.

Written by Cursor Bugbot for commit 741ce8f. This will update automatically on new commits. Configure here.

…8205)

* Fix FT.HYBRID RANGE + FILTER

* FT.HYBRID RANGE sort by ID only when filter is used.

* Add test for RANGE query with FILTER clause in hybrid parsing

* Avoids allocating and immediately freeing a wildcard node for RANGE queries without explicit FILTER

(cherry picked from commit 7348b08)
@nafraf nafraf changed the title [8.4] MOD-12370: Fix FT.HYBRID VSIM RANGE + FILTER returning zero results [8.4] MOD-13885: Fix FT.HYBRID VSIM RANGE + FILTER returning zero results Feb 3, 2026
@codecov
Copy link
Copy Markdown

codecov Bot commented Feb 3, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 85.41%. Comparing base (18de631) to head (741ce8f).
⚠️ Report is 1 commits behind head on 8.4.

Additional details and impacted files
@@            Coverage Diff             @@
##              8.4    #8258      +/-   ##
==========================================
- Coverage   85.46%   85.41%   -0.05%     
==========================================
  Files         335      335              
  Lines       52989    52997       +8     
  Branches    11000    11000              
==========================================
- Hits        45287    45270      -17     
- Misses       7559     7584      +25     
  Partials      143      143              
Flag Coverage Δ
flow 84.29% <100.00%> (-0.17%) ⬇️
unit 51.20% <92.30%> (+0.01%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@redisearch-backport-pull-request redisearch-backport-pull-request Bot added this pull request to the merge queue Feb 3, 2026
Merged via the queue into 8.4 with commit 928aa1b Feb 3, 2026
37 checks passed
@redisearch-backport-pull-request redisearch-backport-pull-request Bot deleted the backport-8205-to-8.4 branch February 3, 2026 17:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant