NAiVE_developer
NAiVE_developer

Reputation: 11

dynamic fields sorting in elasticsearch and.net

I am trying to sort records based on dynamic field names sent to the search API. the d19FilterCriteria object gives me the field name(SortOn) and the order(SortOrder) for sorting. I have used a sort descriptor for this purpose.

   var sortDescriptor = new SortDescriptor<MPANStatus>();
   // If Field Name is Dynamic
 if (d19FilterCriteria.SortOrder == "asc")
  {
    sortDescriptor.Field(d19FilterCriteria.SortOn, Nest.SortOrder.Ascending);
  }
else if (d19FilterCriteria.SortOrder == "desc")
  {
    sortDescriptor.Field(d19FilterCriteria.SortOn, Nest.SortOrder.Descending);
  }

 var result = await _elasticClient.SearchAsync<MPANStatus>(s => s
                 .Index("ampower-mpanstatusindex")
                 .Skip(skip)
                 .Size(pageSize)
                 .Sort(sort => 
                 {
                     sort = sortDescriptor;
                     return sort;
                 })

While debugging the sort descriptor shows me an object that has a valid value for Name and order Value of sort descriptor object while debugging

This query returns empty list for this code. Could I know what the issue here is?

Upvotes: 0

Views: 1820

Answers (3)

Rodolpho Lopes
Rodolpho Lopes

Reputation: 41

The better approach to work with dynamic sorting fields using NEST, it's using SortDescriptor

SortDescriptor<dynamic> sort = GetSorting(request.Sorting);
ISearchResponse result = elasticClient.Search<YourType>(s => s
            .Index("your-index")
            .Sort(s => sort));

Use this method to add a list of sorting

// method to generate the Sorting
public SortDescriptor<dynamic> GetSorting(List<Sort>? sorting) 
{
  SortDescriptor<dynamic> sortDescriptor = new();

  if (sorting != null)
  {
    foreach (Sort sort in sorting)
      sortDescriptor.Field(sort.Field, getOrder(sort.Order));
  }

  return sortDescriptor;
 }

class "Sort" just to store Field and Order values

public string Field { get; set; }
public string Order { get; set; }

Upvotes: 0

Balaji Arun
Balaji Arun

Reputation: 75

My guess is since you are using the dynamic mapping, the string will be considered as text field and sub field keyword use field.keyword instead of just field

Upvotes: 0

Nikunj Banker
Nikunj Banker

Reputation: 773

You can have list of sort order based on your inputs:

List<ISort> sdBookSortOrder = new List<ISort>();
SortOrder oSortOrder = SortOrder.Ascending;  //SortOrder.Descending;
sdBookSortOrder.Add(new FieldSort { Field = <sField1>, Order = oSortOrder });
sdBookSortOrder.Add(new FieldSort { Field = <sField2>, Order = oSortOrder });

And, you can use above sort order collection while sending search request - as shown below:

ISearchRequest searchRequest = new SearchRequest(SearchEngine.IndexName)
  {
    From = iFrom,
    Size = iSize,
    Query = query,
    Sort = oSortOrder,
  };

I hope, it will solve your problem.

Regards, Nikunj

Upvotes: 0

Related Questions