diff --git a/docs/overview/cli.ipynb b/docs/overview/cli.ipynb index 3a3ee147..cf49789b 100644 --- a/docs/overview/cli.ipynb +++ b/docs/overview/cli.ipynb @@ -24,7 +24,7 @@ "name": "stdout", "output_type": "stream", "text": [ - "12:42:18 [RedisVL] INFO RedisVL version 0.8.0\n" + "11:20:38 [RedisVL] INFO RedisVL version 0.8.2\n" ] } ], @@ -300,7 +300,7 @@ "\n", "| Argument | Description | Default |\n", "|----------------|-------------|---------|\n", - "| `-u --url` | The full Redis URL to connec to | `redis://localhost:6379` |\n", + "| `-u --url` | The full Redis URL to connect to | `redis://localhost:6379` |\n", "| `--host` | Redis host to connect to | `localhost` |\n", "| `-p --port` | Redis port to connect to. Must be an integer | `6379` |\n", "| `--user` | Redis username, if one is required | `default` |\n", @@ -339,8 +339,8 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "### Using SSL encription\n", - "If your Redis instance is configured to use SSL encription then set the `--ssl` flag.\n", + "### Using SSL encryption\n", + "If your Redis instance is configured to use SSL encryption then set the `--ssl` flag.\n", "You can similarly specify the username and password to construct the full Redis URL" ] }, @@ -374,7 +374,7 @@ ], "metadata": { "kernelspec": { - "display_name": ".venv", + "display_name": "redisvl-56gG2io_-py3.11", "language": "python", "name": "python3" }, @@ -388,7 +388,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.13.2" + "version": "3.11.9" } }, "nbformat": 4, diff --git a/pyproject.toml b/pyproject.toml index 65dba017..6251a70e 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "redisvl" -version = "0.8.1" +version = "0.8.2" description = "Python client library and CLI for using Redis as a vector database" authors = [{ name = "Redis Inc.", email = "applied.ai@redis.com" }] requires-python = ">=3.9,<3.14" diff --git a/redisvl/query/query.py b/redisvl/query/query.py index 120f14ed..88aa9dfb 100644 --- a/redisvl/query/query.py +++ b/redisvl/query/query.py @@ -939,8 +939,6 @@ def _build_query_string(self) -> str: filter_expression = self._filter_expression if isinstance(filter_expression, FilterExpression): filter_expression = str(filter_expression) - else: - filter_expression = "" text = ( f"@{self._text_field_name}:({self._tokenize_and_escape_query(self._text)})" diff --git a/redisvl/version.py b/redisvl/version.py index 777f190d..deded324 100644 --- a/redisvl/version.py +++ b/redisvl/version.py @@ -1 +1 @@ -__version__ = "0.8.0" +__version__ = "0.8.2" diff --git a/tests/unit/test_query_types.py b/tests/unit/test_query_types.py index 9254ffe4..8cf9b50c 100644 --- a/tests/unit/test_query_types.py +++ b/tests/unit/test_query_types.py @@ -280,6 +280,74 @@ def test_text_query(): text_query = TextQuery(text_string, text_field_name, stopwords=[1, 2, 3]) +def test_text_query_with_string_filter(): + """Test that TextQuery correctly includes string filter expressions in query string. + + This test ensures that when a string filter expression is passed to TextQuery, + it's properly included in the generated query string and not set to empty. + Regression test for bug where string filters were being ignored. + """ + text = "search for document 12345" + text_field_name = "description" + + # Test with string filter expression - should include filter in query string + string_filter = "@category:{tech|science|engineering}" + text_query = TextQuery( + text=text, + text_field_name=text_field_name, + filter_expression=string_filter, + ) + + # Check that filter is stored correctly + assert text_query.filter == string_filter + + # Check that the generated query string includes both text search and filter + query_string = str(text_query) + assert f"@{text_field_name}:(search | document | 12345)" in query_string + assert f"AND {string_filter}" in query_string + assert string_filter in query_string + + # Test with FilterExpression - should also work (existing functionality) + filter_expression = Tag("category") == "tech" + text_query_with_filter_expr = TextQuery( + text=text, + text_field_name=text_field_name, + filter_expression=filter_expression, + ) + + # Check that filter is stored correctly + assert text_query_with_filter_expr.filter == filter_expression + + # Check that the generated query string includes both text search and filter + query_string_with_filter_expr = str(text_query_with_filter_expr) + assert ( + f"@{text_field_name}:(search | document | 12345)" + in query_string_with_filter_expr + ) + assert "AND @category:{tech}" in query_string_with_filter_expr + + # Test with no filter - should only have text search + text_query_no_filter = TextQuery( + text=text, + text_field_name=text_field_name, + ) + + query_string_no_filter = str(text_query_no_filter) + assert f"@{text_field_name}:(search | document | 12345)" in query_string_no_filter + assert "AND" not in query_string_no_filter + + # Test with wildcard filter - should only have text search (no AND clause) + text_query_wildcard = TextQuery( + text=text, + text_field_name=text_field_name, + filter_expression="*", + ) + + query_string_wildcard = str(text_query_wildcard) + assert f"@{text_field_name}:(search | document | 12345)" in query_string_wildcard + assert "AND" not in query_string_wildcard + + @pytest.mark.parametrize( "query", [ diff --git a/uv.lock b/uv.lock index 108e984f..26782e14 100644 --- a/uv.lock +++ b/uv.lock @@ -3593,7 +3593,7 @@ wheels = [ [[package]] name = "redisvl" -version = "0.8.1" +version = "0.8.2" source = { editable = "." } dependencies = [ { name = "jsonpath-ng" },