Skip to content

Commit f68a844

Browse files
authored
Merge branch 'master' into bit-options
2 parents b646dff + 876cafc commit f68a844

File tree

7 files changed

+82
-7
lines changed

7 files changed

+82
-7
lines changed

dev_requirements.txt

+1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
click==8.0.4
12
black==21.11b1
23
flake8==4.0.1
34
flynt~=0.69.0

redis/commands/cluster.py

+11
Original file line numberDiff line numberDiff line change
@@ -275,6 +275,17 @@ class RedisClusterCommands(
275275
r.cluster_info(target_nodes=RedisCluster.ALL_NODES)
276276
"""
277277

278+
def cluster_myid(self, target_node):
279+
"""
280+
Returns the node’s id.
281+
282+
:target_node: 'ClusterNode'
283+
The node to execute the command on
284+
285+
For more information check https://redis.io/commands/cluster-myid/
286+
"""
287+
return self.execute_command("CLUSTER MYID", target_nodes=target_node)
288+
278289
def cluster_addslots(self, target_node, *slots):
279290
"""
280291
Assign new hash slots to receiving node. Sends to specified node.

redis/commands/search/query.py

+12
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ def __init__(self, query_string):
3535
self._highlight_fields = []
3636
self._language = None
3737
self._expander = None
38+
self._dialect = None
3839

3940
def query_string(self):
4041
"""Return the query string of this query only."""
@@ -202,6 +203,8 @@ def _get_args_tags(self):
202203
args += ["LANGUAGE", self._language]
203204
if self._expander:
204205
args += ["EXPANDER", self._expander]
206+
if self._dialect:
207+
args += ["DIALECT", self._dialect]
205208

206209
return args
207210

@@ -288,6 +291,15 @@ def expander(self, expander):
288291
self._expander = expander
289292
return self
290293

294+
def dialect(self, dialect: int) -> "Query":
295+
"""
296+
Add a dialect field to the query.
297+
298+
- **dialect** - dialect version to execute the query under
299+
"""
300+
self._dialect = dialect
301+
return self
302+
291303

292304
class Filter:
293305
def __init__(self, keyword, field, *args):

requirements.txt

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
async-timeout>=4.0.2
22
deprecated>=1.2.3
33
packaging>=20.4
4-
typing-extensions
4+
typing-extensions; python_version<"3.8"

setup.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
long_description_content_type="text/markdown",
99
keywords=["Redis", "key-value store", "database"],
1010
license="MIT",
11-
version="4.2.0",
11+
version="4.2.1",
1212
packages=find_packages(
1313
include=[
1414
"redis",
@@ -35,7 +35,7 @@
3535
"deprecated>=1.2.3",
3636
"packaging>=20.4",
3737
'importlib-metadata >= 1.0; python_version < "3.8"',
38-
"typing-extensions",
38+
'typing-extensions; python_version<"3.8"',
3939
"async-timeout>=4.0.2",
4040
],
4141
classifiers=[

tests/test_cluster.py

+5
Original file line numberDiff line numberDiff line change
@@ -840,6 +840,11 @@ def test_cluster_pubsub_numsub(self, r):
840840
channels = [(b"foo", 1), (b"bar", 2), (b"baz", 3)]
841841
assert r.pubsub_numsub("foo", "bar", "baz", target_nodes="all") == channels
842842

843+
def test_cluster_myid(self, r):
844+
node = r.get_random_node()
845+
myid = r.cluster_myid(node)
846+
assert len(myid) == 40
847+
843848
def test_cluster_slots(self, r):
844849
mock_all_nodes_resp(r, default_cluster_slots)
845850
cluster_slots = r.cluster_slots()

tests/test_search.py

+50-4
Original file line numberDiff line numberDiff line change
@@ -1542,7 +1542,8 @@ def test_vector_field(modclient):
15421542
modclient.hset("b", "v", "aaaabaaa")
15431543
modclient.hset("c", "v", "aaaaabaa")
15441544

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

15481549
assert "a" == res.docs[0].id
@@ -1572,7 +1573,7 @@ def test_text_params(modclient):
15721573
modclient.ft().add_document("doc3", name="Carol")
15731574

15741575
params_dict = {"name1": "Alice", "name2": "Bob"}
1575-
q = Query("@name:($name1 | $name2 )")
1576+
q = Query("@name:($name1 | $name2 )").dialect(2)
15761577
res = modclient.ft().search(q, query_params=params_dict)
15771578
assert 2 == res.total
15781579
assert "doc1" == res.docs[0].id
@@ -1589,7 +1590,7 @@ def test_numeric_params(modclient):
15891590
modclient.ft().add_document("doc3", numval=103)
15901591

15911592
params_dict = {"min": 101, "max": 102}
1592-
q = Query("@numval:[$min $max]")
1593+
q = Query("@numval:[$min $max]").dialect(2)
15931594
res = modclient.ft().search(q, query_params=params_dict)
15941595

15951596
assert 2 == res.total
@@ -1607,7 +1608,7 @@ def test_geo_params(modclient):
16071608
modclient.ft().add_document("doc3", g="29.68746, 34.94882")
16081609

16091610
params_dict = {"lat": "34.95126", "lon": "29.69465", "radius": 1000, "units": "km"}
1610-
q = Query("@g:[$lon $lat $radius $units]")
1611+
q = Query("@g:[$lon $lat $radius $units]").dialect(2)
16111612
res = modclient.ft().search(q, query_params=params_dict)
16121613
assert 3 == res.total
16131614
assert "doc1" == res.docs[0].id
@@ -1631,3 +1632,48 @@ def test_search_commands_in_pipeline(client):
16311632
assert "foo baz" == res[3][2]
16321633
assert res[3][5] is None
16331634
assert res[3][3] == res[3][6] == ["txt", "foo bar"]
1635+
1636+
1637+
@pytest.mark.redismod
1638+
@pytest.mark.onlynoncluster
1639+
@skip_ifmodversion_lt("2.4.3", "search")
1640+
def test_dialect_config(modclient: redis.Redis):
1641+
assert modclient.ft().config_get("DEFAULT_DIALECT") == {"DEFAULT_DIALECT": "1"}
1642+
assert modclient.ft().config_set("DEFAULT_DIALECT", 2)
1643+
assert modclient.ft().config_get("DEFAULT_DIALECT") == {"DEFAULT_DIALECT": "2"}
1644+
with pytest.raises(redis.ResponseError):
1645+
modclient.ft().config_set("DEFAULT_DIALECT", 0)
1646+
1647+
1648+
@pytest.mark.redismod
1649+
@skip_ifmodversion_lt("2.4.3", "search")
1650+
def test_dialect(modclient: redis.Redis):
1651+
modclient.ft().create_index(
1652+
(
1653+
TagField("title"),
1654+
TextField("t1"),
1655+
TextField("t2"),
1656+
NumericField("num"),
1657+
VectorField(
1658+
"v", "HNSW", {"TYPE": "FLOAT32", "DIM": 1, "DISTANCE_METRIC": "COSINE"}
1659+
),
1660+
)
1661+
)
1662+
modclient.hset("h", "t1", "hello")
1663+
with pytest.raises(redis.ResponseError) as err:
1664+
modclient.ft().explain(Query("(*)").dialect(1))
1665+
assert "Syntax error" in str(err)
1666+
assert "WILDCARD" in modclient.ft().explain(Query("(*)").dialect(2))
1667+
1668+
with pytest.raises(redis.ResponseError) as err:
1669+
modclient.ft().explain(Query("$hello").dialect(1))
1670+
assert "Syntax error" in str(err)
1671+
q = Query("$hello").dialect(2)
1672+
expected = "UNION {\n hello\n +hello(expanded)\n}\n"
1673+
assert expected in modclient.ft().explain(q, query_params={"hello": "hello"})
1674+
1675+
expected = "NUMERIC {0.000000 <= @num <= 10.000000}\n"
1676+
assert expected in modclient.ft().explain(Query("@title:(@num:[0 10])").dialect(1))
1677+
with pytest.raises(redis.ResponseError) as err:
1678+
modclient.ft().explain(Query("@title:(@num:[0 10])").dialect(2))
1679+
assert "Syntax error" in str(err)

0 commit comments

Comments
 (0)