From b45f4820c0559a56e0be7c13ac197f9dbfae82c1 Mon Sep 17 00:00:00 2001 From: MuddyHope Date: Thu, 29 Aug 2024 04:47:43 +0530 Subject: [PATCH 1/5] Federated Search Addition --- meilisearch/client.py | 7 ++++-- .../test_client_multi_search_meilisearch.py | 25 +++++++++++++++++++ 2 files changed, 30 insertions(+), 2 deletions(-) diff --git a/meilisearch/client.py b/meilisearch/client.py index 094f8392..f48af625 100644 --- a/meilisearch/client.py +++ b/meilisearch/client.py @@ -219,7 +219,7 @@ def index(self, uid: str) -> Index: return Index(self.config, uid=uid) raise ValueError("The index UID should not be None") - def multi_search(self, queries: Sequence[Mapping[str, Any]]) -> Dict[str, List[Dict[str, Any]]]: + def multi_search(self, queries: Sequence[Mapping[str, Any]], federation: Optional[Dict[str, Any]] = None) -> Dict[str, List[Dict[str, Any]]]: """Multi-index search. Parameters @@ -227,6 +227,9 @@ def multi_search(self, queries: Sequence[Mapping[str, Any]]) -> Dict[str, List[D queries: List of dictionaries containing the specified indexes and their search queries https://www.meilisearch.com/docs/reference/api/search#search-in-an-index + federation: (optional): + List of dictionaries containing offset and limit + https://www.meilisearch.com/docs/reference/api/multi_search Returns ------- @@ -240,7 +243,7 @@ def multi_search(self, queries: Sequence[Mapping[str, Any]]) -> Dict[str, List[D """ return self.http.post( f"{self.config.paths.multi_search}", - body={"queries": queries}, + body={"queries": queries, "federation": federation}, ) def get_all_stats(self) -> Dict[str, Any]: diff --git a/tests/client/test_client_multi_search_meilisearch.py b/tests/client/test_client_multi_search_meilisearch.py index 904d1bca..0a4bf999 100644 --- a/tests/client/test_client_multi_search_meilisearch.py +++ b/tests/client/test_client_multi_search_meilisearch.py @@ -32,3 +32,28 @@ def test_multi_search_on_no_index(client): """Tests multi-search on a non existing index.""" with pytest.raises(MeilisearchApiError): client.multi_search([{"indexUid": "indexDoesNotExist", "q": ""}]) + + +def test_multi_search_with_no_value_in_federation(client, empty_index): + """Tests multi-search with federation, but no value""" + empty_index("indexA") + response = client.multi_search([{"indexUid": "indexA", "q": ""}], {}) + + assert response["hits"][0]["_federation"]['indexUid'] == "indexA" if len(response["hits"]) >= 1 else isinstance(response, dict) + + +def test_multi_search_with_offset_and_limit_in_federation(client, empty_index): + """Tests multi-search with federation, with offset and limit value""" + empty_index("indexA") + response = client.multi_search([{"indexUid": "indexA", "q": ""}], {"offset": 2, "limit": 2}) + + assert len(response["hits"]) == 2 if response['hits'] else True + + +def test_multi_search_with_federation_options(client, empty_index): + """Tests multi-search with federation, with federation options""" + empty_index("indexA") + response = client.multi_search([{"indexUid": "indexA", "q": "", "federationOptions": {"weight": 0.99}}], {"offset": 2, "limit": 2}) + + assert isinstance(response["hits"], list) + assert response["hits"][0]["_federation"]["weightedRankingScore"] < 0.99 if len(response["hits"]) >= 1 else True From 007f40f07f9a77e984c494324cd90fc599b31137 Mon Sep 17 00:00:00 2001 From: MuddyHope Date: Thu, 29 Aug 2024 10:53:31 +0530 Subject: [PATCH 2/5] Updating test cases and docstring --- meilisearch/client.py | 2 +- .../test_client_multi_search_meilisearch.py | 43 +++++++++++++------ 2 files changed, 30 insertions(+), 15 deletions(-) diff --git a/meilisearch/client.py b/meilisearch/client.py index f48af625..a396b243 100644 --- a/meilisearch/client.py +++ b/meilisearch/client.py @@ -228,7 +228,7 @@ def multi_search(self, queries: Sequence[Mapping[str, Any]], federation: Optiona List of dictionaries containing the specified indexes and their search queries https://www.meilisearch.com/docs/reference/api/search#search-in-an-index federation: (optional): - List of dictionaries containing offset and limit + Dictionary containing offset and limit https://www.meilisearch.com/docs/reference/api/multi_search Returns diff --git a/tests/client/test_client_multi_search_meilisearch.py b/tests/client/test_client_multi_search_meilisearch.py index 0a4bf999..78892764 100644 --- a/tests/client/test_client_multi_search_meilisearch.py +++ b/tests/client/test_client_multi_search_meilisearch.py @@ -1,6 +1,7 @@ import pytest from meilisearch.errors import MeilisearchApiError +from tests.common import INDEX_UID def test_basic_multi_search(client, empty_index): @@ -34,26 +35,40 @@ def test_multi_search_on_no_index(client): client.multi_search([{"indexUid": "indexDoesNotExist", "q": ""}]) -def test_multi_search_with_no_value_in_federation(client, empty_index): +def test_multi_search_with_no_value_in_federation(client, empty_index, index_with_documents): """Tests multi-search with federation, but no value""" - empty_index("indexA") - response = client.multi_search([{"indexUid": "indexA", "q": ""}], {}) - - assert response["hits"][0]["_federation"]['indexUid'] == "indexA" if len(response["hits"]) >= 1 else isinstance(response, dict) - + index_with_documents() + empty_index("indexB") + response = client.multi_search( + [{"indexUid": INDEX_UID, "q": ""}, {"indexUid": "indexB", "q": ""}], {} + ) + assert "results" not in response + assert len(response["hits"]) > 0 + assert "_federation" in response["hits"][0] + assert response["limit"] == 20 + assert response["offset"] == 0 -def test_multi_search_with_offset_and_limit_in_federation(client, empty_index): +def test_multi_search_with_offset_and_limit_in_federation(client, index_with_documents): """Tests multi-search with federation, with offset and limit value""" - empty_index("indexA") - response = client.multi_search([{"indexUid": "indexA", "q": ""}], {"offset": 2, "limit": 2}) + index_with_documents() + response = client.multi_search([{"indexUid": INDEX_UID, "q": ""}], {"offset": 2, "limit": 2}) - assert len(response["hits"]) == 2 if response['hits'] else True + assert "results" not in response + assert len(response["hits"]) == 2 + assert "_federation" in response["hits"][0] + assert response["limit"] == 2 + assert response["offset"] == 2 -def test_multi_search_with_federation_options(client, empty_index): +def test_multi_search_with_federation_options(client, index_with_documents): """Tests multi-search with federation, with federation options""" - empty_index("indexA") - response = client.multi_search([{"indexUid": "indexA", "q": "", "federationOptions": {"weight": 0.99}}], {"offset": 2, "limit": 2}) + index_with_documents() + response = client.multi_search([{"indexUid": INDEX_UID, "q": "", "federationOptions": {"weight": 0.99}}], {"limit": 2}) + assert "results" not in response + assert response["hits"][0]["_federation"]["indexUid"] == INDEX_UID assert isinstance(response["hits"], list) - assert response["hits"][0]["_federation"]["weightedRankingScore"] < 0.99 if len(response["hits"]) >= 1 else True + assert response["hits"][0]["_federation"]["weightedRankingScore"] >= 0.99 + assert len(response["hits"]) == 2 + assert response["limit"] == 2 + assert response["offset"] == 0 From 59f2098f036a90f3fdb38a2d203b8e7fa31383fd Mon Sep 17 00:00:00 2001 From: MuddyHope Date: Thu, 29 Aug 2024 11:57:28 +0530 Subject: [PATCH 3/5] flake8 fix max-line-length --- meilisearch/client.py | 3 ++- .../test_client_multi_search_meilisearch.py | 17 ++++++++++++----- 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/meilisearch/client.py b/meilisearch/client.py index a396b243..6689fa29 100644 --- a/meilisearch/client.py +++ b/meilisearch/client.py @@ -219,7 +219,8 @@ def index(self, uid: str) -> Index: return Index(self.config, uid=uid) raise ValueError("The index UID should not be None") - def multi_search(self, queries: Sequence[Mapping[str, Any]], federation: Optional[Dict[str, Any]] = None) -> Dict[str, List[Dict[str, Any]]]: + def multi_search(self, queries: Sequence[Mapping[str, Any]], + federation: Optional[Dict[str, Any]] = None) -> Dict[str, List[Dict[str, Any]]]: """Multi-index search. Parameters diff --git a/tests/client/test_client_multi_search_meilisearch.py b/tests/client/test_client_multi_search_meilisearch.py index 78892764..1adbadd4 100644 --- a/tests/client/test_client_multi_search_meilisearch.py +++ b/tests/client/test_client_multi_search_meilisearch.py @@ -35,7 +35,8 @@ def test_multi_search_on_no_index(client): client.multi_search([{"indexUid": "indexDoesNotExist", "q": ""}]) -def test_multi_search_with_no_value_in_federation(client, empty_index, index_with_documents): +def test_multi_search_with_no_value_in_federation(client, empty_index, + index_with_documents): """Tests multi-search with federation, but no value""" index_with_documents() empty_index("indexB") @@ -48,11 +49,15 @@ def test_multi_search_with_no_value_in_federation(client, empty_index, index_wit assert response["limit"] == 20 assert response["offset"] == 0 -def test_multi_search_with_offset_and_limit_in_federation(client, index_with_documents): + +def test_multi_search_with_offset_and_limit_in_federation( + client, + index_with_documents): """Tests multi-search with federation, with offset and limit value""" index_with_documents() - response = client.multi_search([{"indexUid": INDEX_UID, "q": ""}], {"offset": 2, "limit": 2}) - + response = client.multi_search([{"indexUid": INDEX_UID, "q": ""}], + {"offset": 2, "limit": 2}) + assert "results" not in response assert len(response["hits"]) == 2 assert "_federation" in response["hits"][0] @@ -63,7 +68,9 @@ def test_multi_search_with_offset_and_limit_in_federation(client, index_with_doc def test_multi_search_with_federation_options(client, index_with_documents): """Tests multi-search with federation, with federation options""" index_with_documents() - response = client.multi_search([{"indexUid": INDEX_UID, "q": "", "federationOptions": {"weight": 0.99}}], {"limit": 2}) + response = client.multi_search( + [{"indexUid": INDEX_UID, "q": "", + "federationOptions": {"weight": 0.99}}], {"limit": 2}) assert "results" not in response assert response["hits"][0]["_federation"]["indexUid"] == INDEX_UID From d060e26ec41e12f73a534ed7f24d3a0e1ac08ccb Mon Sep 17 00:00:00 2001 From: MuddyHope <60110059+MuddyHope@users.noreply.github.com> Date: Thu, 29 Aug 2024 14:57:14 +0530 Subject: [PATCH 4/5] Update tests/client/test_client_multi_search_meilisearch.py Co-authored-by: Paul Sanders --- tests/client/test_client_multi_search_meilisearch.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/client/test_client_multi_search_meilisearch.py b/tests/client/test_client_multi_search_meilisearch.py index 1adbadd4..c14f4ca3 100644 --- a/tests/client/test_client_multi_search_meilisearch.py +++ b/tests/client/test_client_multi_search_meilisearch.py @@ -73,9 +73,9 @@ def test_multi_search_with_federation_options(client, index_with_documents): "federationOptions": {"weight": 0.99}}], {"limit": 2}) assert "results" not in response - assert response["hits"][0]["_federation"]["indexUid"] == INDEX_UID assert isinstance(response["hits"], list) - assert response["hits"][0]["_federation"]["weightedRankingScore"] >= 0.99 assert len(response["hits"]) == 2 + assert response["hits"][0]["_federation"]["indexUid"] == INDEX_UID + assert response["hits"][0]["_federation"]["weightedRankingScore"] >= 0.99 assert response["limit"] == 2 assert response["offset"] == 0 From 2361c9d5d0db3f544db1f3e50999e67491316fdb Mon Sep 17 00:00:00 2001 From: MuddyHope Date: Thu, 29 Aug 2024 15:01:41 +0530 Subject: [PATCH 5/5] requested changes --- meilisearch/client.py | 5 +++-- .../client/test_client_multi_search_meilisearch.py | 14 +++++--------- 2 files changed, 8 insertions(+), 11 deletions(-) diff --git a/meilisearch/client.py b/meilisearch/client.py index 6689fa29..981cb2c1 100644 --- a/meilisearch/client.py +++ b/meilisearch/client.py @@ -219,8 +219,9 @@ def index(self, uid: str) -> Index: return Index(self.config, uid=uid) raise ValueError("The index UID should not be None") - def multi_search(self, queries: Sequence[Mapping[str, Any]], - federation: Optional[Dict[str, Any]] = None) -> Dict[str, List[Dict[str, Any]]]: + def multi_search( + self, queries: Sequence[Mapping[str, Any]], federation: Optional[Dict[str, Any]] = None + ) -> Dict[str, List[Dict[str, Any]]]: """Multi-index search. Parameters diff --git a/tests/client/test_client_multi_search_meilisearch.py b/tests/client/test_client_multi_search_meilisearch.py index c14f4ca3..3d888bf3 100644 --- a/tests/client/test_client_multi_search_meilisearch.py +++ b/tests/client/test_client_multi_search_meilisearch.py @@ -35,8 +35,7 @@ def test_multi_search_on_no_index(client): client.multi_search([{"indexUid": "indexDoesNotExist", "q": ""}]) -def test_multi_search_with_no_value_in_federation(client, empty_index, - index_with_documents): +def test_multi_search_with_no_value_in_federation(client, empty_index, index_with_documents): """Tests multi-search with federation, but no value""" index_with_documents() empty_index("indexB") @@ -50,13 +49,10 @@ def test_multi_search_with_no_value_in_federation(client, empty_index, assert response["offset"] == 0 -def test_multi_search_with_offset_and_limit_in_federation( - client, - index_with_documents): +def test_multi_search_with_offset_and_limit_in_federation(client, index_with_documents): """Tests multi-search with federation, with offset and limit value""" index_with_documents() - response = client.multi_search([{"indexUid": INDEX_UID, "q": ""}], - {"offset": 2, "limit": 2}) + response = client.multi_search([{"indexUid": INDEX_UID, "q": ""}], {"offset": 2, "limit": 2}) assert "results" not in response assert len(response["hits"]) == 2 @@ -69,8 +65,8 @@ def test_multi_search_with_federation_options(client, index_with_documents): """Tests multi-search with federation, with federation options""" index_with_documents() response = client.multi_search( - [{"indexUid": INDEX_UID, "q": "", - "federationOptions": {"weight": 0.99}}], {"limit": 2}) + [{"indexUid": INDEX_UID, "q": "", "federationOptions": {"weight": 0.99}}], {"limit": 2} + ) assert "results" not in response assert isinstance(response["hits"], list)