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?

user3749920
  • 123
  • 1
  • 1
  • 4

6 Answers6

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()
    )
Greg Marzouka
  • 3,315
  • 1
  • 20
  • 17
  • 7
    This no longer works. Multiple .Sort(...) would lead to the last one overwriting all the previous sort commands. – Magnus O. Sep 27 '17 at 08:36
  • the answer below should be marked as correct answer – Allie May 28 '20 at 13:24
  • 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. – Sbu Mar 10 '22 at 15:15
10

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)
    )
);
Magnus O.
  • 468
  • 5
  • 17
  • 1
    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. – levininja Dec 01 '17 at 20:15
  • 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). – levininja Dec 01 '17 at 20:26
  • .Sort( sort => sort .Field(i => i .Field(ii => ii.Year == 0) .Order(SortOrder.Descending) ) ) .Sort(sort=> sort .Ascending(f => f.Year) ) – levininja Dec 04 '17 at 20:00
  • 4
    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) ) ) – Magnus O. Dec 05 '17 at 07:20
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)
        );
Jay Shah
  • 3,553
  • 1
  • 27
  • 26
2
searchDescriptor
    .Sort(s => s
          .Ascending(a => a.OrgId)
          .Descending(d => d.CreateTimeInUtc)
    );
Udhav Sarvaiya
  • 9,380
  • 13
  • 53
  • 64
Shaoming
  • 39
  • 3
1

The following works in NEST 7.12:

new SortDescriptor<Subject>()
    .Ascending(f => f.CurrentRunStarted)
    .Ascending(f => f.LastRunDate)
Craig Eddy
  • 889
  • 1
  • 6
  • 17
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())
    )
danvasiloiu
  • 751
  • 7
  • 24