Sorting on Multiple Fields
Asked Answered
M

6

12

Does Nest support sorting on multiple fields? For example, say I want to sort first by FieldA ascending and then by FieldB descending.

My current approach looks something like this:

searchDescriptor.Sort(s =>s.OnField("FieldA").Ascending().OnField("FieldB").Descending());

But the "FieldB".Descending() part seems to be the only sort option that is sent to elasticsearch.

Does anyone know if there is another way to accomplish this?

Magnitude answered 17/9, 2014 at 15:25 Comment(0)
S
11

You are adding multiple fields on the same sort descriptor, which is overriding the previous value. Instead, you need to specify a new sort descriptor for each field:

searchDescriptor
    .Sort(s => s
        .OnField("FieldA")
        .Ascending()
    )
    .Sort(s => s
        .OnField("FieldB")
        .Descending()
    )
Scrupulous answered 17/9, 2014 at 15:47 Comment(3)
This no longer works. Multiple .Sort(...) would lead to the last one overwriting all the previous sort commands.Lonnalonnard
the answer below should be marked as correct answerSubdiaconate
Tried with Elastic server 2.4.6 and Nest 2.5.8 here, this compiles but does not work. The answer from @MagnusO. below works and should be accepted instead.Keese
L
11

I recent version of Nest the correct way of sortin on multiple fileds would be:

.Sort(s => s
    Field(f => f
        .Field("FieldA")
        .Order(SortOrder.Ascending)
    )
    .Field(f => f
        .Field("FieldB")
        .Order(SortOrder.Ascending)
    )
);
Lonnalonnard answered 27/9, 2017 at 8:35 Comment(4)
I have the latest version of ES Nest and I'm writing the exact same code as you have in this example but it isn't working; it is only applying the last sort (FieldB in your example). Please let me know if there is anything else to get it to work.Triatomic
Edit: this appears to be working if you specify simple fields ("FieldA" and "FieldB" in your example) but not if you are using a function as one of your sorts (even though the same function works if used by itself as the only sort function).Triatomic
.Sort( sort => sort .Field(i => i .Field(ii => ii.Year == 0) .Order(SortOrder.Descending) ) ) .Sort(sort=> sort .Ascending(f => f.Year) )Triatomic
Test this: ..Sort(sort => sort .Field(i => i .Field(ii => ii.Year == 0) .Order(SortOrder.Descending) ) .Field(i => i .Field(ii => ii.Year) .Order(SortOrder.Ascending) ) )Lonnalonnard
K
4

for sorting on multiple dynamic fields, SortDescriptor can be useful.

        var sortDescriptor = new SortDescriptor<{YourType}>();

        sortDescriptor.Field(f => f.YourFieldName, Nest.SortOrder.Ascending);

        // If Field Name is Dynamic
        sortDescriptor.Field(
            "someOtherFieldName",
            Nest.SortOrder.Descending);         

        var searchResponse = await client.SearchAsync<{YourType}>(x => x
        .Query(y => query)
        .Sort(s => sortDescriptor)
        .From(from)
        .Size(size)
        );
Kowtow answered 24/5, 2017 at 10:46 Comment(0)
C
2
searchDescriptor
    .Sort(s => s
          .Ascending(a => a.OrgId)
          .Descending(d => d.CreateTimeInUtc)
    );
Capuchin answered 17/11, 2018 at 4:35 Comment(0)
F
1

The following works in NEST 7.12:

new SortDescriptor<Subject>()
    .Ascending(f => f.CurrentRunStarted)
    .Ascending(f => f.LastRunDate)
Future answered 1/7, 2021 at 11:3 Comment(0)
L
0

You can use it like this. You also can use the names from your model.

   EsClient.Search<Business>(s => s
      .Query (qq=> {...})
      .Sort(sort => sort.OnField(s => s.Name).Descending())
      .Sort(sort => sort.OnField(s => s.Age).Descending())
    )
Lai answered 12/1, 2015 at 16:51 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.