diff --git a/meilisearch/client.py b/meilisearch/client.py index a8c87325..e3572d32 100644 --- a/meilisearch/client.py +++ b/meilisearch/client.py @@ -252,6 +252,33 @@ def multi_search( body={"queries": queries, "federation": federation}, ) + def update_documents_by_function( + self, index_uid: str, queries: Dict[str, List[Dict[str, Any]]] + ) -> Dict[str, Any]: + """Update Documents by function + Parameters + ---------- + index_uid: + The index_uid where you want to update documents of. + queries: + List of dictionaries containing functions with or without filters that you want to use to update documents. + + Returns + ------- + task_info: + TaskInfo instance containing information about a task to track the progress of an asynchronous process. + https://www.meilisearch.com/docs/reference/api/tasks#get-one-task + + Raises + ------ + MeilisearchApiError + An error containing details about why Meilisearch can't process your request. Meilisearch error codes are described here: https://www.meilisearch.com/docs/reference/errors/error_codes#meilisearch-errors + """ + return self.http.post( + path=f"{self.config.paths.index}/{index_uid}/{self.config.paths.document}/{self.config.paths.edit}", + body=dict(queries), + ) + def get_all_stats(self) -> Dict[str, Any]: """Get all stats of Meilisearch diff --git a/meilisearch/config.py b/meilisearch/config.py index 1d40a694..acf5745b 100644 --- a/meilisearch/config.py +++ b/meilisearch/config.py @@ -44,6 +44,7 @@ class Paths: search_cutoff_ms = "search-cutoff-ms" proximity_precision = "proximity-precision" localized_attributes = "localized-attributes" + edit = "edit" def __init__( self, diff --git a/tests/client/test_client_update_document_by_functions.py b/tests/client/test_client_update_document_by_functions.py new file mode 100644 index 00000000..8a809908 --- /dev/null +++ b/tests/client/test_client_update_document_by_functions.py @@ -0,0 +1,17 @@ +import pytest + +from tests.common import INDEX_UID + + +@pytest.mark.usefixtures("enable_edit_documents_by_function") +def test_update_document_by_function(client, index_with_documents): + """Delete the document with id and update document title""" + index_with_documents() + response = client.update_documents_by_function( + INDEX_UID, + {"function": 'if doc.id == "522681" {doc = () } else {doc.title = `* ${doc.title} *`}'}, + ) + + assert isinstance(response, dict) + assert isinstance(response["taskUid"], int) + assert response["indexUid"] == INDEX_UID diff --git a/tests/conftest.py b/tests/conftest.py index a16359eb..7a814ff7 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 @@ -233,6 +234,40 @@ def get_private_key(client): 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, + ) + + +@fixture +def enable_edit_documents_by_function(): + requests.patch( + f"{common.BASE_URL}/experimental-features", + headers={"Authorization": f"Bearer {common.MASTER_KEY}"}, + json={"editDocumentsByFunction": True}, + timeout=10, + ) + yield + requests.patch( + f"{common.BASE_URL}/experimental-features", + headers={"Authorization": f"Bearer {common.MASTER_KEY}"}, + json={"editDocumentsByFunction": False}, + timeout=10, + ) + + @fixture def new_embedders(): return { diff --git a/tests/index/test_index_document_meilisearch.py b/tests/index/test_index_document_meilisearch.py index df52e7d4..7c7a4579 100644 --- a/tests/index/test_index_document_meilisearch.py +++ b/tests/index/test_index_document_meilisearch.py @@ -171,7 +171,6 @@ def test_update_documents_json_custom_serializer(empty_index): def test_update_documents_raw_custom_serializer(empty_index): - documents = [ {"id": uuid4(), "title": "test 1", "when": datetime.now()}, {"id": uuid4(), "title": "Test 2", "when": datetime.now()},