Skip to content

Conversation

@petyaslavova
Copy link
Collaborator

Pull Request check-list

Please make sure to review and check all of these items:

  • Do tests and lints pass with this change?
  • Do the CI tests pass with this change (enable it first in your forked repo and wait for the github action build to finish)?
  • Is the new or changed code fully tested?
  • Is a documentation update included (if this change modifies existing APIs, or introduces new ones)?
  • Is there an example added to the examples folder (if applicable)?

NOTE: these things are not required to open a PR and can be done
afterwards / while the PR is open.

Description of change

Please provide a description of the change here.

@petyaslavova petyaslavova requested a review from Copilot October 24, 2025 09:22
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull Request Overview

This PR adds support for hybrid search functionality to the Redis search client, enabling combined text and vector similarity searches. The implementation introduces new query types, result parsers, and comprehensive test coverage.

Key changes:

  • New hybrid query classes for combining text search and vector similarity operations
  • Hybrid search command execution and result parsing
  • Post-processing configuration for filtering, sorting, and aggregating results

Reviewed Changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
tests/test_search.py Comprehensive test suite covering hybrid search functionality including various query types, filters, and post-processing options
redis/connection.py Minor whitespace cleanup (removed blank line)
redis/commands/search/hybrid_query.py New file implementing hybrid query classes and post-processing configuration
redis/commands/search/commands.py Added hybrid_search method and result parsing logic
redis/commands/search/init.py Registered hybrid search command parser

Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.

@petyaslavova petyaslavova added the feature New feature label Oct 24, 2025
@petyaslavova petyaslavova force-pushed the ps_add_hybrid_search branch 3 times, most recently from 1e8345a to 3b3b4f5 Compare October 29, 2025 08:13
@petyaslavova petyaslavova marked this pull request as draft October 29, 2025 08:17
@petyaslavova petyaslavova changed the title Adding support for hybrid search. Adding support for HYBRID search. Nov 3, 2025
@petyaslavova petyaslavova requested a review from Copilot November 3, 2025 12:39
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull Request Overview

Copilot reviewed 6 out of 7 changed files in this pull request and generated 8 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@petyaslavova petyaslavova force-pushed the ps_add_hybrid_search branch 2 times, most recently from 0ea7eec to fc7c324 Compare November 4, 2025 10:55
@petyaslavova petyaslavova marked this pull request as ready for review November 4, 2025 10:58
@petyaslavova petyaslavova requested a review from Copilot November 4, 2025 11:36
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull Request Overview

Copilot reviewed 5 out of 6 changed files in this pull request and generated 4 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

def scorer(self, scorer: str) -> "HybridSearchQuery":
"""
Scoring algorithm for text search query.
Allowed values are "TFIDF" or "BM25"
Copy link
Collaborator

Choose a reason for hiding this comment

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

Allowed values are type?: 'BM25' | 'TFIDF' | 'DISMAX' | 'DOCSCORE' according to the design. Also maybe it makes sense to keep value as Enum so we don't need to add validation around it?

"""Return the query string of this query object."""
return self._query_string

def scorer(self, scorer: str) -> "HybridSearchQuery":
Copy link
Collaborator

Choose a reason for hiding this comment

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

Apart of scorer algorithm, scorer also supports named parameters

SCORER algorithm params...

Add search method parameters to the query.
Args:
method: Vector search method name. Supported values are "KNN" or "RANGE".
Copy link
Collaborator

Choose a reason for hiding this comment

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

Enum value could be used

Args:
method: Vector search method name. Supported values are "KNN" or "RANGE".
kwargs: Search method parameters. Use the param names for keys and the
values for the values. Example: {"K": 10, "EF_RUNTIME": 100}.
Copy link
Collaborator

Choose a reason for hiding this comment

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

K is a required argument, whereas EF_RUNTIME is optional. Makes sense to add some validation around it

conditions: Filter conditions.
"""
args = [conditions]
Filter.__init__(self, "FILTER", *args)
Copy link
Collaborator

Choose a reason for hiding this comment

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

Filters are way more complex then this.

[FILTER] "<filter-expression>"
       [POLICY [ADHOC/BATCHES/ACORN]]
           [BATCHES BATCH_SIZE <batch-size-value>]


def combine(
self,
method: Literal["RRF", "LINEAR"],
Copy link
Collaborator

Choose a reason for hiding this comment

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

Design also specifies third one: FUNCTION. PRD also mentioned it

Args:
method: The combine method to use - RRF or LINEAR.
kwargs: Additional combine parameters.
Copy link
Collaborator

Choose a reason for hiding this comment

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

Same problem here, isn't really clear which parameters could be used with which method


ret = ["GROUPBY", str(len(fields)), *fields]
for reducer in reducers:
ret += ["REDUCE", reducer.NAME, str(len(reducer.args))]
Copy link
Collaborator

Choose a reason for hiding this comment

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

So it needs to add REDUCE for each reducer? From PRD it seems that it accepts count argument and single REDUCE keyword. Also, it doesn't says about aliases. Correct me if I'm wrong

[GROUPBY count field... REDUCE function count...]

the alias for the projection, and the value is the projection
expression itself, for example `apply(square_root="sqrt(@foo)")`.
"""
for alias, expr in kwexpr.items():
Copy link
Collaborator

Choose a reason for hiding this comment

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

PRD also doesn't specifies an option to have multiple APPLY keywords


return self

def sort_by(self, *sortby: "SortbyField") -> Self:
Copy link
Collaborator

Choose a reason for hiding this comment

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

Looks like SortByField is missing WITHCOUNT option

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

Labels

feature New feature

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants