diff --git a/meilisearch/index.py b/meilisearch/index.py index 67e46ab9..41586bde 100644 --- a/meilisearch/index.py +++ b/meilisearch/index.py @@ -243,6 +243,7 @@ def get_stats(self) -> IndexStats: stats = self.http.get(f"{self.config.paths.index}/{self.uid}/{self.config.paths.stat}") return IndexStats(stats) + @version_error_hint_message def search(self, query: str, opt_params: Optional[Dict[str, Any]] = None) -> Dict[str, Any]: """Search in the index. @@ -251,7 +252,13 @@ def search(self, query: str, opt_params: Optional[Dict[str, Any]] = None) -> Dic query: String containing the searched word(s) opt_params (optional): - Dictionary containing optional query parameters + Dictionary containing optional query parameters. + Note: The vector parameter is only available in Meilisearch >= v1.3.0, and is experimental + Meilisearch v1.3.0. In order to use this feature in Meilisearch v1.3.0 you first need to + enable the feature by sending a PATCH request to /experimental-features with + { "vectoreStore": true }. Because this feature is experimental it may be removed or + updated causing breaking changes in this library without a major version bump so use + with caution. https://www.meilisearch.com/docs/reference/api/search#search-in-an-index Returns diff --git a/tests/conftest.py b/tests/conftest.py index 797649ff..e8f64c13 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -2,6 +2,7 @@ import json from typing import Optional +import requests from pytest import fixture import meilisearch @@ -126,6 +127,19 @@ def index_maker(index_uid=common.INDEX_UID, documents=small_movies): return index_maker +@fixture(scope="function") +def index_with_documents_and_vectors(empty_index, small_movies): + small_movies[0]["_vectors"] = [0.1, 0.2] + + def index_maker(index_uid=common.INDEX_UID, documents=small_movies): + index = empty_index(index_uid) + task = index.add_documents(documents) + index.wait_for_task(task.task_uid) + return index + + return index_maker + + @fixture(scope="function") def test_key(client): key_info = { @@ -172,3 +186,20 @@ def get_private_key(client): keys = client.get_keys().results key = next(x for x in keys if "Default Search API" in x.name) return key + + +@fixture +def enable_vector_search(): + requests.patch( + f"{common.BASE_URL}/experimental-features", + headers={"Authorization": f"Bearer {common.MASTER_KEY}"}, + json={"vectorStore": True}, + timeout=10, + ) + yield + requests.patch( + f"{common.BASE_URL}/experimental-features", + headers={"Authorization": f"Bearer {common.MASTER_KEY}"}, + json={"vectorStore": False}, + timeout=10, + ) diff --git a/tests/index/test_index_search_meilisearch.py b/tests/index/test_index_search_meilisearch.py index 77995b1a..67eddee8 100644 --- a/tests/index/test_index_search_meilisearch.py +++ b/tests/index/test_index_search_meilisearch.py @@ -1,5 +1,7 @@ # pylint: disable=invalid-name +import pytest + def test_basic_search(index_with_documents): """Tests search with a simple query.""" @@ -441,3 +443,13 @@ def test_custom_search_params_with_pagination_parameters_at_zero(index_with_docu assert response["totalPages"] is not None assert response["totalHits"] is not None assert "estimatedTotalHits" is not response + + +@pytest.mark.usefixtures("enable_vector_search") +def test_vector_search(index_with_documents_and_vectors): + response = index_with_documents_and_vectors().search( + "How to Train Your Dragon", opt_params={"vector": [0.1, 0.2]} + ) + + assert response["hits"][0]["id"] == "287947" + assert response["vector"] == [0.1, 0.2]