Skip to content

Commit 4eff5a5

Browse files
authored
Merge pull request #492 from sanders41/meilisearch-1.2.0
Update for Meilisearch v1.2.0
2 parents a82ecea + 57326af commit 4eff5a5

File tree

2 files changed

+138
-4
lines changed

2 files changed

+138
-4
lines changed

meilisearch_python_async/index.py

Lines changed: 83 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -394,7 +394,12 @@ async def get_document(self, document_id: str) -> dict[str, Any]:
394394
return response.json()
395395

396396
async def get_documents(
397-
self, *, offset: int = 0, limit: int = 20, fields: list[str] | None = None
397+
self,
398+
*,
399+
offset: int = 0,
400+
limit: int = 20,
401+
fields: list[str] | None = None,
402+
filter: str | list[str | list[str]] | None = None,
398403
) -> DocumentsInfo:
399404
"""Get a batch documents from the index.
400405
@@ -404,6 +409,8 @@ async def get_documents(
404409
limit: Maximum number of documents returnedd. Defaults to 20.
405410
fields: Document attributes to show. If this value is None then all
406411
attributes are retrieved. Defaults to None.
412+
filter: Filter value information. Defaults to None. Note: This parameter can only be
413+
used with Meilisearch >= v1.2.0
407414
408415
Returns:
409416
@@ -427,11 +434,22 @@ async def get_documents(
427434
"limit": limit,
428435
}
429436

437+
if not filter:
438+
if fields:
439+
parameters["fields"] = ",".join(fields)
440+
441+
url = f"{self._documents_url}?{urlencode(parameters)}"
442+
response = await self._http_requests.get(url)
443+
444+
return DocumentsInfo(**response.json())
445+
430446
if fields:
431-
parameters["fields"] = ",".join(fields)
447+
parameters["fields"] = fields
432448

433-
url = f"{self._documents_url}?{urlencode(parameters)}"
434-
response = await self._http_requests.get(url)
449+
parameters["filter"] = filter
450+
451+
url = f"{self._documents_url}/fetch"
452+
response = await self._http_requests.post(url, body=parameters)
435453

436454
return DocumentsInfo(**response.json())
437455

@@ -1307,6 +1325,67 @@ async def delete_documents(self, ids: list[str]) -> TaskInfo:
13071325

13081326
return TaskInfo(**response.json())
13091327

1328+
async def delete_documents_by_filter(self, filter: str | list[str | list[str]]) -> TaskInfo:
1329+
"""Delete documents from the index by filter.
1330+
1331+
Args:
1332+
1333+
filter: The filter value information.
1334+
1335+
Returns:
1336+
1337+
The details of the task status.
1338+
1339+
Raises:
1340+
1341+
MeilisearchCommunicationError: If there was an error communicating with the server.
1342+
MeilisearchApiError: If the Meilisearch API returned an error.
1343+
1344+
Examples:
1345+
1346+
>>> from meilisearch_python_async import Client
1347+
>>> async with Client("http://localhost.com", "masterKey") as client:
1348+
>>> index = client.index("movies")
1349+
>>> await index.delete_documents_by_filter("genre=horor"))
1350+
"""
1351+
url = f"{self._documents_url}/delete"
1352+
response = await self._http_requests.post(url, body={"filter": filter})
1353+
1354+
return TaskInfo(**response.json())
1355+
1356+
async def delete_documents_in_batches_by_filter(
1357+
self, filters: list[str | list[str | list[str]]]
1358+
) -> list[TaskInfo]:
1359+
"""Delete batches of documents from the index by filter.
1360+
1361+
Args:
1362+
1363+
filters: A list of filter value information.
1364+
1365+
Returns:
1366+
1367+
The a list of details of the task statuses.
1368+
1369+
Raises:
1370+
1371+
MeilisearchCommunicationError: If there was an error communicating with the server.
1372+
MeilisearchApiError: If the Meilisearch API returned an error.
1373+
1374+
Examples:
1375+
1376+
>>> from meilisearch_python_async import Client
1377+
>>> async with Client("http://localhost.com", "masterKey") as client:
1378+
>>> index = client.index("movies")
1379+
>>> await index.delete_documents_in_batches_by_filter(
1380+
>>> [
1381+
>>> "genre=horor"),
1382+
>>> "release_date=1520035200"),
1383+
>>> ]
1384+
>>> )
1385+
"""
1386+
tasks = [self.delete_documents_by_filter(filter) for filter in filters]
1387+
return await gather(*tasks)
1388+
13101389
async def delete_all_documents(self) -> TaskInfo:
13111390
"""Delete all documents from the index.
13121391

tests/test_documents.py

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -574,6 +574,26 @@ async def test_get_documents_offset_optional_params(index_with_documents):
574574
assert response_offset_limit.results[0]["overview"] == response.results[1]["overview"]
575575

576576

577+
async def test_get_documents_filter(index_with_documents):
578+
index = await index_with_documents()
579+
response = await index.update_filterable_attributes(["genre"])
580+
await wait_for_task(index.http_client, response.task_uid)
581+
response = await index.get_documents(filter="genre=action")
582+
genres = set([x["genre"] for x in response.results])
583+
assert len(genres) == 1
584+
assert next(iter(genres)) == "action"
585+
586+
587+
async def test_get_documents_filter_with_fields(index_with_documents):
588+
index = await index_with_documents()
589+
response = await index.update_filterable_attributes(["genre"])
590+
await wait_for_task(index.http_client, response.task_uid)
591+
response = await index.get_documents(fields=["genre"], filter="genre=action")
592+
genres = set([x["genre"] for x in response.results])
593+
assert len(genres) == 1
594+
assert next(iter(genres)) == "action"
595+
596+
577597
async def test_update_documents(index_with_documents, small_movies):
578598
index = await index_with_documents()
579599
response = await index.get_documents()
@@ -1138,6 +1158,41 @@ async def test_delete_documents(index_with_documents):
11381158
assert to_delete not in ids
11391159

11401160

1161+
async def test_delete_documents_by_filter(index_with_documents):
1162+
index = await index_with_documents()
1163+
response = await index.update_filterable_attributes(["genre"])
1164+
await wait_for_task(index.http_client, response.task_uid)
1165+
response = await index.get_documents()
1166+
assert "action" in ([x.get("genre") for x in response.results])
1167+
response = await index.delete_documents_by_filter("genre=action")
1168+
await wait_for_task(index.http_client, response.task_uid)
1169+
response = await index.get_documents()
1170+
genres = [x.get("genre") for x in response.results]
1171+
assert "action" not in genres
1172+
assert "cartoon" in genres
1173+
1174+
1175+
async def test_delete_documents_in_batches_by_filter(index_with_documents):
1176+
index = await index_with_documents()
1177+
response = await index.update_filterable_attributes(["genre", "release_date"])
1178+
await wait_for_task(index.http_client, response.task_uid)
1179+
response = await index.get_documents()
1180+
assert "action" in [x.get("genre") for x in response.results]
1181+
assert 1520035200 in [x.get("release_date") for x in response.results]
1182+
response = await index.delete_documents_in_batches_by_filter(
1183+
["genre=action", "release_date=1520035200"]
1184+
)
1185+
for task in response:
1186+
await wait_for_task(index.http_client, task.task_uid)
1187+
response = await index.get_documents()
1188+
genres = [x.get("genre") for x in response.results]
1189+
release_dates = [x.get("release_date") for x in response.results]
1190+
assert "action" not in genres
1191+
assert "cartoon" in genres
1192+
assert len(release_dates) > 0
1193+
assert 1520035200 not in release_dates
1194+
1195+
11411196
async def test_delete_all_documents(index_with_documents):
11421197
index = await index_with_documents()
11431198
response = await index.delete_all_documents()

0 commit comments

Comments
 (0)