Skip to content

Commit fd4fff6

Browse files
authored
Merge pull request #1163 from awais786/my-new-branch
Add support for sorting on the documents API.
2 parents a54e3c2 + 979ac38 commit fd4fff6

File tree

3 files changed

+87
-2
lines changed

3 files changed

+87
-2
lines changed

.code-samples.meilisearch.yaml

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,12 +24,16 @@ get_one_document_1: |-
2424
'fields': ['id', 'title', 'poster', 'release_date']
2525
})
2626
get_documents_1: |-
27-
client.index('movies').get_documents({'limit':2, 'filter': 'genres=action'})
27+
client.index('movies').get_documents({
28+
'limit':2, 'filter': 'genres=action',
29+
'sort': ['rating:desc', 'release_date:asc'] # list format
30+
})
2831
get_documents_post_1: |-
2932
client.index('books').get_documents({
3033
'limit':3,
3134
'fields': ['title', 'genres', 'rating', 'language'],
32-
'filter': '(rating > 3 AND (genres=Adventure OR genres=Fiction)) AND language=English'
35+
'filter': '(rating > 3 AND (genres=Adventure OR genres=Fiction)) AND language=English',
36+
'sort': 'rating:desc, title:asc' # comma-separated string format
3337
})
3438
add_or_replace_documents_1: |-
3539
client.index('movies').add_documents([{

meilisearch/index.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -403,6 +403,7 @@ def get_documents(
403403
- offset
404404
- limit
405405
- results : list of Document instances containing the documents information
406+
- sort: A list of attributes written as an array or as a comma-separated string
406407
407408
Raises
408409
------
@@ -411,6 +412,12 @@ def get_documents(
411412
"""
412413
if parameters is None:
413414
parameters = {}
415+
416+
# convert comma-separated sort string to list
417+
sort = parameters.get("sort")
418+
if isinstance(sort, str):
419+
parameters["sort"] = [s.strip() for s in sort.split(",") if s.strip()]
420+
414421
response = self.http.post(
415422
f"{self.config.paths.index}/{self.uid}/{self.config.paths.document}/fetch",
416423
body=parameters,

tests/index/test_index_document_meilisearch.py

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -245,6 +245,80 @@ def test_get_documents_offset_optional_params_list_of_fields(index_with_document
245245
assert response_offset_limit.results[0].genre == response.results[1].genre
246246

247247

248+
def test_get_documents_sort_fields(index_with_documents):
249+
"""Tests getting documents sorted by fields."""
250+
index = index_with_documents()
251+
252+
# Make fields sortable: include 'rating' and 'release_date'
253+
sortable_attributes = ["rating", "release_date"]
254+
task = index.update_sortable_attributes(sortable_attributes)
255+
index.wait_for_task(task.task_uid) # wait until sortable attributes are set
256+
257+
documents = [
258+
{"id": 1, "title": "Inception", "release_date": "2010-07-16", "rating": 8.8},
259+
{"id": 2, "title": "Interstellar", "release_date": "2014-11-07", "rating": 8.6},
260+
{"id": 3, "title": "Parasite", "release_date": "2019-05-30", "rating": 8.6},
261+
{"id": 4, "title": "The Matrix", "release_date": "1999-03-31", "rating": 8.7},
262+
{"id": 5, "title": "The Dark Knight", "release_date": "2008-07-18", "rating": 9.0},
263+
]
264+
265+
# Add documents
266+
task = index.add_documents(documents)
267+
index.wait_for_task(task.task_uid)
268+
269+
params = {
270+
"limit": 5,
271+
"fields": ["id", "title", "release_date", "rating"],
272+
"sort": ["rating:desc", "release_date:asc"],
273+
}
274+
response = index.get_documents(params)
275+
276+
# prepare expected order
277+
sorted_docs = sorted(documents, key=lambda d: (-d["rating"], d["release_date"]))
278+
279+
for resp_doc, expected_doc in zip(response.results, sorted_docs):
280+
assert resp_doc.id == expected_doc["id"]
281+
assert resp_doc.rating == expected_doc["rating"]
282+
assert resp_doc.release_date == expected_doc["release_date"]
283+
284+
285+
@pytest.mark.parametrize(
286+
"sort_param",
287+
[
288+
["rating:desc", "release_date:asc"], # list format
289+
"rating:desc, release_date:asc", # comma-separated string
290+
],
291+
)
292+
def test_get_documents_sort_formats(index_with_documents, sort_param):
293+
index = index_with_documents()
294+
295+
# Make fields sortable
296+
sortable_attributes = ["rating", "release_date"]
297+
task = index.update_sortable_attributes(sortable_attributes)
298+
index.wait_for_task(task.task_uid)
299+
300+
documents = [
301+
{"id": 1, "title": "Inception", "release_date": "2010-07-16", "rating": 8.8},
302+
{"id": 2, "title": "Interstellar", "release_date": "2014-11-07", "rating": 8.6},
303+
{"id": 3, "title": "Parasite", "release_date": "2019-05-30", "rating": 8.6},
304+
{"id": 4, "title": "The Matrix", "release_date": "1999-03-31", "rating": 8.7},
305+
{"id": 5, "title": "The Dark Knight", "release_date": "2008-07-18", "rating": 9.0},
306+
]
307+
308+
task = index.add_documents(documents)
309+
index.wait_for_task(task.task_uid)
310+
311+
params = {"limit": 5, "fields": ["id", "title", "release_date", "rating"], "sort": sort_param}
312+
response = index.get_documents(params)
313+
314+
sorted_docs = sorted(documents, key=lambda d: (-d["rating"], d["release_date"]))
315+
316+
for resp_doc, expected_doc in zip(response.results, sorted_docs):
317+
assert resp_doc.id == expected_doc["id"]
318+
assert resp_doc.rating == expected_doc["rating"]
319+
assert resp_doc.release_date == expected_doc["release_date"]
320+
321+
248322
def test_get_documents_filter(index_with_documents):
249323
index = index_with_documents()
250324
response = index.update_filterable_attributes(["genre"])

0 commit comments

Comments
 (0)