From df89e5183174327eb67b8b5c065af27756ad36b5 Mon Sep 17 00:00:00 2001 From: Hristo Temelski Date: Thu, 31 Jul 2025 12:50:22 +0300 Subject: [PATCH 1/4] added epsilon property to the vsim command --- redis/commands/vectorset/commands.py | 7 +++++++ tests/test_vsets.py | 13 +++++++++++++ 2 files changed, 20 insertions(+) diff --git a/redis/commands/vectorset/commands.py b/redis/commands/vectorset/commands.py index c24bd200ce..0f23dba10d 100644 --- a/redis/commands/vectorset/commands.py +++ b/redis/commands/vectorset/commands.py @@ -129,6 +129,7 @@ def vsim( filter_ef: Optional[str] = None, truth: Optional[bool] = False, no_thread: Optional[bool] = False, + epsilon: Optional[Number] = None, ) -> Union[ Awaitable[Optional[List[Union[List[EncodableT], Dict[EncodableT, Number]]]]], Optional[List[Union[List[EncodableT], Dict[EncodableT, Number]]]], @@ -152,6 +153,9 @@ def vsim( ``no_thread`` when enabled forces the command to execute the search on the data structure in the main thread. + ``epsilon`` floating point between 0 and 1, if specified will return + only elements with distance no further than the specified one. + For more information see https://redis.io/commands/vsim """ @@ -176,6 +180,9 @@ def vsim( if count: pieces.extend(["COUNT", count]) + if epsilon: + pieces.extend(["EPSILON", epsilon]) + if ef: pieces.extend(["EF", ef]) diff --git a/tests/test_vsets.py b/tests/test_vsets.py index 4a9d95bc1f..2ea5bec3f9 100644 --- a/tests/test_vsets.py +++ b/tests/test_vsets.py @@ -424,6 +424,19 @@ def test_vsim_truth_no_thread_enabled(d_client): assert len(sim_no_thread) == 10 assert isinstance(sim_no_thread, dict) +@skip_if_server_version_lt("8.2.0") +def test_vsim_epsilon(d_client): + d_client.vset().vadd("myset", [2, 1, 1], "a") + d_client.vset().vadd("myset", [2, 0, 1], "b") + d_client.vset().vadd("myset", [2, 0, 0], "c") + d_client.vset().vadd("myset", [2, 0, -1], "d") + d_client.vset().vadd("myset", [2, -1, -1], "e") + + res1 = d_client.vset().vsim("myset", [2, 1, 1]) + assert 5 == len(res1) + + res2 = d_client.vset().vsim("myset", [2, 1, 1], epsilon=0.5) + assert 3 == len(res2) @skip_if_server_version_lt("7.9.0") def test_vdim(d_client): From f8b12787e2f6590e5b2efffdb83bd2f60d468685 Mon Sep 17 00:00:00 2001 From: Hristo Temelski Date: Thu, 31 Jul 2025 12:53:40 +0300 Subject: [PATCH 2/4] fixed linter errors --- tests/test_vsets.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/test_vsets.py b/tests/test_vsets.py index 2ea5bec3f9..38776cc102 100644 --- a/tests/test_vsets.py +++ b/tests/test_vsets.py @@ -424,6 +424,7 @@ def test_vsim_truth_no_thread_enabled(d_client): assert len(sim_no_thread) == 10 assert isinstance(sim_no_thread, dict) + @skip_if_server_version_lt("8.2.0") def test_vsim_epsilon(d_client): d_client.vset().vadd("myset", [2, 1, 1], "a") @@ -438,6 +439,7 @@ def test_vsim_epsilon(d_client): res2 = d_client.vset().vsim("myset", [2, 1, 1], epsilon=0.5) assert 3 == len(res2) + @skip_if_server_version_lt("7.9.0") def test_vdim(d_client): float_array = [1, 4.32, 0.11, 0.5, 0.9, 0.1, 0.2] From f1e5325aaa3f31afeafd2158e04798f67dc91170 Mon Sep 17 00:00:00 2001 From: Hristo Temelski Date: Fri, 1 Aug 2025 13:18:25 +0300 Subject: [PATCH 3/4] added async client test --- tests/test_asyncio/test_vsets.py | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/tests/test_asyncio/test_vsets.py b/tests/test_asyncio/test_vsets.py index 4ae336acf8..b86fb8e331 100644 --- a/tests/test_asyncio/test_vsets.py +++ b/tests/test_asyncio/test_vsets.py @@ -423,6 +423,21 @@ async def test_vsim_truth_no_thread_enabled(d_client): assert isinstance(sim_no_thread, dict) +@skip_if_server_version_lt("8.2.0") +def test_vsim_epsilon(d_client): + d_client.vset().vadd("myset", [2, 1, 1], "a") + d_client.vset().vadd("myset", [2, 0, 1], "b") + d_client.vset().vadd("myset", [2, 0, 0], "c") + d_client.vset().vadd("myset", [2, 0, -1], "d") + d_client.vset().vadd("myset", [2, -1, -1], "e") + + res1 = d_client.vset().vsim("myset", [2, 1, 1]) + assert 5 == len(res1) + + res2 = d_client.vset().vsim("myset", [2, 1, 1], epsilon=0.5) + assert 3 == len(res2) + + @skip_if_server_version_lt("7.9.0") async def test_vdim(d_client): float_array = [1, 4.32, 0.11, 0.5, 0.9, 0.1, 0.2] From 7ea0015d47321f6ce17b34d73082f2fa0e56e285 Mon Sep 17 00:00:00 2001 From: Hristo Temelski Date: Fri, 1 Aug 2025 13:37:54 +0300 Subject: [PATCH 4/4] modified test to use async --- tests/test_asyncio/test_vsets.py | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/tests/test_asyncio/test_vsets.py b/tests/test_asyncio/test_vsets.py index b86fb8e331..01c2f3c95a 100644 --- a/tests/test_asyncio/test_vsets.py +++ b/tests/test_asyncio/test_vsets.py @@ -424,17 +424,17 @@ async def test_vsim_truth_no_thread_enabled(d_client): @skip_if_server_version_lt("8.2.0") -def test_vsim_epsilon(d_client): - d_client.vset().vadd("myset", [2, 1, 1], "a") - d_client.vset().vadd("myset", [2, 0, 1], "b") - d_client.vset().vadd("myset", [2, 0, 0], "c") - d_client.vset().vadd("myset", [2, 0, -1], "d") - d_client.vset().vadd("myset", [2, -1, -1], "e") - - res1 = d_client.vset().vsim("myset", [2, 1, 1]) +async def test_vsim_epsilon(d_client): + await d_client.vset().vadd("myset", [2, 1, 1], "a") + await d_client.vset().vadd("myset", [2, 0, 1], "b") + await d_client.vset().vadd("myset", [2, 0, 0], "c") + await d_client.vset().vadd("myset", [2, 0, -1], "d") + await d_client.vset().vadd("myset", [2, -1, -1], "e") + + res1 = await d_client.vset().vsim("myset", [2, 1, 1]) assert 5 == len(res1) - res2 = d_client.vset().vsim("myset", [2, 1, 1], epsilon=0.5) + res2 = await d_client.vset().vsim("myset", [2, 1, 1], epsilon=0.5) assert 3 == len(res2)