Skip to content

Commit

Permalink
Changed default dialect to 2
Browse files Browse the repository at this point in the history
  • Loading branch information
vladvildanov committed Dec 26, 2024
1 parent 8e2f2d3 commit 7fafc82
Show file tree
Hide file tree
Showing 3 changed files with 78 additions and 27 deletions.
2 changes: 1 addition & 1 deletion redis/commands/search/aggregation.py
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ def __init__(self, query: str = "*") -> None:
self._with_schema = False
self._verbatim = False
self._cursor = []
self._dialect = None
self._dialect = 2
self._add_scores = False
self._scorer = "TFIDF"

Expand Down
2 changes: 1 addition & 1 deletion redis/commands/search/query.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ def __init__(self, query_string: str) -> None:
self._highlight_fields: List = []
self._language: Optional[str] = None
self._expander: Optional[str] = None
self._dialect: Optional[int] = None
self._dialect: int = 2

def query_string(self) -> str:
"""Return the query string of this query only."""
Expand Down
101 changes: 76 additions & 25 deletions tests/test_search.py
Original file line number Diff line number Diff line change
Expand Up @@ -2122,7 +2122,7 @@ def test_profile_query_params(client):
client.hset("b", "v", "aaaabaaa")
client.hset("c", "v", "aaaaabaa")
query = "*=>[KNN 2 @v $vec]"
q = Query(query).return_field("__v_score").sort_by("__v_score", True).dialect(2)
q = Query(query).return_field("__v_score").sort_by("__v_score", True)
if is_resp2_connection(client):
res, det = client.ft().profile(q, query_params={"vec": "aaaaaaaa"})
assert det["Iterators profile"]["Counter"] == 2.0
Expand Down Expand Up @@ -2155,7 +2155,7 @@ def test_vector_field(client):
client.hset("c", "v", "aaaaabaa")

query = "*=>[KNN 2 @v $vec]"
q = Query(query).return_field("__v_score").sort_by("__v_score", True).dialect(2)
q = Query(query).return_field("__v_score").sort_by("__v_score", True)
res = client.ft().search(q, query_params={"vec": "aaaaaaaa"})

if is_resp2_connection(client):
Expand Down Expand Up @@ -2191,7 +2191,7 @@ def test_text_params(client):
client.hset("doc3", mapping={"name": "Carol"})

params_dict = {"name1": "Alice", "name2": "Bob"}
q = Query("@name:($name1 | $name2 )").dialect(2)
q = Query("@name:($name1 | $name2 )")
res = client.ft().search(q, query_params=params_dict)
if is_resp2_connection(client):
assert 2 == res.total
Expand All @@ -2214,7 +2214,7 @@ def test_numeric_params(client):
client.hset("doc3", mapping={"numval": 103})

params_dict = {"min": 101, "max": 102}
q = Query("@numval:[$min $max]").dialect(2)
q = Query("@numval:[$min $max]")
res = client.ft().search(q, query_params=params_dict)

if is_resp2_connection(client):
Expand All @@ -2236,7 +2236,7 @@ def test_geo_params(client):
client.hset("doc3", mapping={"g": "29.68746, 34.94882"})

params_dict = {"lat": "34.95126", "lon": "29.69465", "radius": 1000, "units": "km"}
q = Query("@g:[$lon $lat $radius $units]").dialect(2)
q = Query("@g:[$lon $lat $radius $units]")
res = client.ft().search(q, query_params=params_dict)
_assert_search_result(client, res, ["doc1", "doc2", "doc3"])

Expand Down Expand Up @@ -2355,19 +2355,19 @@ def test_dialect(client):
with pytest.raises(redis.ResponseError) as err:
client.ft().explain(Query("(*)").dialect(1))
assert "Syntax error" in str(err)
assert "WILDCARD" in client.ft().explain(Query("(*)").dialect(2))
assert "WILDCARD" in client.ft().explain(Query("(*)"))

with pytest.raises(redis.ResponseError) as err:
client.ft().explain(Query("$hello").dialect(1))
assert "Syntax error" in str(err)
q = Query("$hello").dialect(2)
q = Query("$hello")
expected = "UNION {\n hello\n +hello(expanded)\n}\n"
assert expected in client.ft().explain(q, query_params={"hello": "hello"})

expected = "NUMERIC {0.000000 <= @num <= 10.000000}\n"
assert expected in client.ft().explain(Query("@title:(@num:[0 10])").dialect(1))
with pytest.raises(redis.ResponseError) as err:
client.ft().explain(Query("@title:(@num:[0 10])").dialect(2))
client.ft().explain(Query("@title:(@num:[0 10])"))
assert "Syntax error" in str(err)


Expand Down Expand Up @@ -2438,9 +2438,9 @@ def test_withsuffixtrie(client: redis.Redis):
@pytest.mark.redismod
def test_query_timeout(r: redis.Redis):
q1 = Query("foo").timeout(5000)
assert q1.get_args() == ["foo", "TIMEOUT", 5000, "LIMIT", 0, 10]
assert q1.get_args() == ["foo", "TIMEOUT", 5000, "DIALECT", 2, "LIMIT", 0, 10]
q1 = Query("foo").timeout(0)
assert q1.get_args() == ["foo", "TIMEOUT", 0, "LIMIT", 0, 10]
assert q1.get_args() == ["foo", "TIMEOUT", 0, "DIALECT", 2, "LIMIT", 0, 10]
q2 = Query("foo").timeout("not_a_number")
with pytest.raises(redis.ResponseError):
r.ft().search(q2)
Expand Down Expand Up @@ -2508,27 +2508,27 @@ def test_search_missing_fields(client):

with pytest.raises(redis.exceptions.ResponseError) as e:
client.ft().search(
Query("ismissing(@title)").dialect(2).return_field("id").no_content()
Query("ismissing(@title)").return_field("id").no_content()
)
assert "to be defined with 'INDEXMISSING'" in e.value.args[0]

res = client.ft().search(
Query("ismissing(@features)").dialect(2).return_field("id").no_content()
Query("ismissing(@features)").return_field("id").no_content()
)
_assert_search_result(client, res, ["property:2"])

res = client.ft().search(
Query("-ismissing(@features)").dialect(2).return_field("id").no_content()
Query("-ismissing(@features)").return_field("id").no_content()
)
_assert_search_result(client, res, ["property:1", "property:3"])

res = client.ft().search(
Query("ismissing(@description)").dialect(2).return_field("id").no_content()
Query("ismissing(@description)").return_field("id").no_content()
)
_assert_search_result(client, res, ["property:3"])

res = client.ft().search(
Query("-ismissing(@description)").dialect(2).return_field("id").no_content()
Query("-ismissing(@description)").return_field("id").no_content()
)
_assert_search_result(client, res, ["property:1", "property:2"])

Expand Down Expand Up @@ -2579,29 +2579,29 @@ def test_search_empty_fields(client):

with pytest.raises(redis.exceptions.ResponseError) as e:
client.ft().search(
Query("@title:''").dialect(2).return_field("id").no_content()
Query("@title:''").return_field("id").no_content()
)
assert "Use `INDEXEMPTY` in field creation" in e.value.args[0]

res = client.ft().search(
Query("@features:{$empty}").dialect(2).return_field("id").no_content(),
Query("@features:{$empty}").return_field("id").no_content(),
query_params={"empty": ""},
)
_assert_search_result(client, res, ["property:2"])

res = client.ft().search(
Query("-@features:{$empty}").dialect(2).return_field("id").no_content(),
Query("-@features:{$empty}").return_field("id").no_content(),
query_params={"empty": ""},
)
_assert_search_result(client, res, ["property:1", "property:3"])

res = client.ft().search(
Query("@description:''").dialect(2).return_field("id").no_content()
Query("@description:''").return_field("id").no_content()
)
_assert_search_result(client, res, ["property:3"])

res = client.ft().search(
Query("-@description:''").dialect(2).return_field("id").no_content()
Query("-@description:''").return_field("id").no_content()
)
_assert_search_result(client, res, ["property:1", "property:2"])

Expand Down Expand Up @@ -2643,29 +2643,80 @@ def test_special_characters_in_fields(client):

# no need to escape - when using params
res = client.ft().search(
Query("@uuid:{$uuid}").dialect(2),
Query("@uuid:{$uuid}"),
query_params={"uuid": "123e4567-e89b-12d3-a456-426614174000"},
)
_assert_search_result(client, res, ["resource:1"])

# with double quotes exact match no need to escape the - even without params
res = client.ft().search(
Query('@uuid:{"123e4567-e89b-12d3-a456-426614174000"}').dialect(2)
Query('@uuid:{"123e4567-e89b-12d3-a456-426614174000"}')
)
_assert_search_result(client, res, ["resource:1"])

res = client.ft().search(Query('@tags:{"new-year\'s-resolutions"}').dialect(2))
res = client.ft().search(Query('@tags:{"new-year\'s-resolutions"}'))
_assert_search_result(client, res, ["resource:2"])

# possible to search numeric fields by single value
res = client.ft().search(Query("@rating:[4]").dialect(2))
res = client.ft().search(Query("@rating:[4]"))
_assert_search_result(client, res, ["resource:2"])

# some chars still need escaping
res = client.ft().search(Query(r"@tags:{\$btc}").dialect(2))
res = client.ft().search(Query(r"@tags:{\$btc}"))
_assert_search_result(client, res, ["resource:1"])


@pytest.mark.redismod
@skip_ifmodversion_lt("2.4.3", "search")
def test_vector_search_with_default_dialect(client):
client.ft().create_index(
(
VectorField(
"v", "HNSW", {"TYPE": "FLOAT32", "DIM": 2, "DISTANCE_METRIC": "L2"}
),
)
)

client.hset("a", "v", "aaaaaaaa")
client.hset("b", "v", "aaaabaaa")
client.hset("c", "v", "aaaaabaa")

query = "*=>[KNN 2 @v $vec]"
q = Query(query)

assert "DIALECT" in q.get_args()
assert 2 in q.get_args()

res = client.ft().search(q, query_params={"vec": "aaaaaaaa"})
assert res.total == 2

@pytest.mark.redismod
@skip_ifmodversion_lt("2.4.3", "search")
def test_search_query_with_different_dialects(client):
client.ft().create_index(
(
TextField("name"),
TextField("lastname")
),
definition=IndexDefinition(prefix=["test:"])
)

client.hset("test:1", "name", "James")
client.hset("test:1", "lastname", "Brown")

# Query with default DIALECT 2
query = "@name: James Brown"
q = Query(query)
res = client.ft().search(q)
assert res.total == 1

# Query with explicit DIALECT 1
query = "@name: James Brown"
q = Query(query).dialect(1)
res = client.ft().search(q)
assert res.total == 0


def _assert_search_result(client, result, expected_doc_ids):
"""
Make sure the result of a geo search is as expected, taking into account the RESP
Expand Down

0 comments on commit 7fafc82

Please sign in to comment.