Skip to content

Commit 1592132

Browse files
Merge #666
666: Add support for sort in documents api r=curquiza a=kashifsoofi # Pull Request ## Related issue Fixes #665 ## What does this PR do? - Add Sort to DocumentsQuery ## PR checklist Please check if your PR fulfills the following requirements: - [x] Does this PR fix an existing issue, or have you listed the changes applied in the PR description (and why they are needed)? - [x] Have you read the contributing guidelines? - [x] Have you made sure that the title is accurate and descriptive of the changes? Thank you so much for contributing to Meilisearch! <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Added support for sorting document query results, including multi-field ordering and ID-based sorts; works with filters and limits. * **Documentation** * Added "Search with sort" guidance and a C# example showing how to specify sort options. * **Tests** * Added tests validating ascending/descending, multi-field sort with filters, and that sort parameters appear in query strings. * **Chores** * Bumped Meilisearch version used in CI from v1.10.0 to v1.16. <!-- end of auto-generated comment: release notes by coderabbit.ai --> Co-authored-by: Kashif Soofi <[email protected]>
2 parents c29f7dd + 1be21f6 commit 1592132

File tree

5 files changed

+91
-1
lines changed

5 files changed

+91
-1
lines changed

.env

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
1-
MEILISEARCH_VERSION=v1.10.0
1+
MEILISEARCH_VERSION=v1.16
22
PROXIED_MEILISEARCH=http://nginx/api/
33
MEILISEARCH_URL=http://meilisearch:7700

README.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -260,6 +260,17 @@ if (results is PaginatedSearchResult<T> paginatedResults)
260260
}
261261
```
262262

263+
#### Search with sort
264+
265+
To get results sorted by attributes and preferred sorting order, the [Sort](https://www.meilisearch.com/docs/reference/api/search#sort) property must be defined.
266+
267+
```c#
268+
var results = await index.SearchAsync<T>(query, new SearchQuery()
269+
{
270+
Sort = new List<string> { "genre:asc", "name:desc" }
271+
});
272+
```
273+
263274
## 🤖 Compatibility with Meilisearch
264275

265276
This package guarantees compatibility with [version v1.x of Meilisearch](https://github.com/meilisearch/meilisearch/releases/latest), but some features may not be present. Please check the [issues](https://github.com/meilisearch/meilisearch-dotnet/issues?q=is%3Aissue+is%3Aopen+label%3A%22good+first+issue%22+label%3Aenhancement) for more info.

src/Meilisearch/QueryParameters/DocumentsQuery.cs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,5 +31,11 @@ public class DocumentsQuery
3131
/// </summary>
3232
[JsonPropertyName("filter")]
3333
public object Filter { get; set; }
34+
35+
/// <summary>
36+
/// An optional sort to apply
37+
/// </summary>
38+
[JsonPropertyName("sort")]
39+
public List<string> Sort { get; set; }
3440
}
3541
}

tests/Meilisearch.Tests/DocumentTests.cs

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -643,6 +643,64 @@ await index.GetDocumentsAsync<Movie>(new DocumentsQuery()
643643
documents.Results.Last().Id.Should().Be("11");
644644
}
645645

646+
[Theory]
647+
[InlineData("id:asc", true)]
648+
[InlineData("id:desc", false)]
649+
public async Task GetMultipleExistingDocumentsWithIdSort(string sort, bool ascending)
650+
{
651+
var index = await _fixture.SetUpBasicIndexWithIntId($"GetMultipleExistingDocumentsWithIdSort_{(ascending ? "Asc" : "Desc")}Test");
652+
var updateSortable = await index.UpdateSortableAttributesAsync(new[] { "id" });
653+
updateSortable.TaskUid.Should().BeGreaterOrEqualTo(0);
654+
await index.WaitForTaskAsync(updateSortable.TaskUid);
655+
656+
var results = (await index.GetDocumentsAsync<MovieWithIntId>(
657+
new DocumentsQuery { Sort = new List<string> { sort } }
658+
)).Results.ToList();
659+
660+
Assert.Equal(7, results.Count);
661+
if (ascending)
662+
results.Should().BeInAscendingOrder(x => x.Id);
663+
else
664+
results.Should().BeInDescendingOrder(x => x.Id);
665+
}
666+
667+
[Fact]
668+
public async Task GetMultipleExistingDocumentsWithMultiSort()
669+
{
670+
var index = await _fixture.SetUpBasicIndexWithIntId("GetMultipleExistingDocumentsWithMultiSort");
671+
var updateFilterable = await index.UpdateFilterableAttributesAsync(new[] { "genre" });
672+
updateFilterable.TaskUid.Should().BeGreaterOrEqualTo(0);
673+
await index.WaitForTaskAsync(updateFilterable.TaskUid);
674+
675+
var updateSortable = await index.UpdateSortableAttributesAsync(new[] { "genre", "name" });
676+
updateSortable.TaskUid.Should().BeGreaterOrEqualTo(0);
677+
await index.WaitForTaskAsync(updateSortable.TaskUid);
678+
679+
var results = (await index.GetDocumentsAsync<MovieWithIntId>(
680+
new DocumentsQuery
681+
{
682+
Filter = "genre IN ['SF','Action']",
683+
Sort = new List<string> { "genre:asc", "name:desc" }
684+
}
685+
)).Results.ToList();
686+
687+
Assert.Equal(4, results.Count);
688+
var first = results.First();
689+
first.Genre.Should().Be("Action");
690+
first.Name.Should().Be("Spider-Man");
691+
var last = results.Last();
692+
last.Genre.Should().Be("SF");
693+
last.Name.Should().Be("Harry Potter");
694+
695+
results.Should().BeInAscendingOrder(x => x.Genre);
696+
var split = results.FindIndex(x => x.Genre == "SF");
697+
split.Should().BeGreaterThan(0); // at least one Action before SF
698+
results.Take(split).Should().OnlyContain(x => x.Genre == "Action");
699+
results.Skip(split).Should().OnlyContain(x => x.Genre == "SF");
700+
results.Take(split).Should().BeInDescendingOrder(x => x.Name);
701+
results.Skip(split).Should().BeInDescendingOrder(x => x.Name);
702+
}
703+
646704
[Fact]
647705
public async Task DeleteOneExistingDocumentWithStringId()
648706
{

tests/Meilisearch.Tests/ObjectExtensionsTests.cs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
using System;
22
using System.Collections.Generic;
3+
using System.Linq;
34

45
using Meilisearch.Extensions;
56
using Meilisearch.QueryParameters;
@@ -157,5 +158,19 @@ public void QueryStringsWithListAreEqualsForDocumentsQuery(int? offset, int? lim
157158
Assert.Contains(String.Join(",", dq.Fields), actualQuery);
158159
}
159160
}
161+
162+
[Theory]
163+
[InlineData(null, new string[] { "id:asc", "title:desc" })]
164+
public void QueryStringsWithSortAreEqualForDocumentsQuery(int? limit, string[] sort)
165+
{
166+
var uri = "indexes/myindex/documents";
167+
var dq = new DocumentsQuery { Limit = limit, Sort = sort.ToList() };
168+
var actualQuery = dq.ToQueryString(uri: uri);
169+
170+
Assert.NotEmpty(actualQuery);
171+
Assert.NotNull(actualQuery);
172+
Assert.Contains("sort", actualQuery);
173+
Assert.Contains(String.Join(",", dq.Sort), actualQuery);
174+
}
160175
}
161176
}

0 commit comments

Comments
 (0)