Search code examples
c#elasticsearchnest

Elastic Nest Passing Dynamic Values into Sort


I have My Elastic Query working well, I have aggregations and I have it sorting on a particular field, but if the user wants to say sort it on price, how can i dynamically change the sort field, without putting a switch statement around the entire query to select a different field.

my current query:

.Sort(ss => ss
                    .Field(f => f
                        .Field(ff => ff.DispatchTimeInDays)
                        .Order(Nest.SortOrder.Ascending)
                        )
                    )

Solution

  • You can do this in the Field lambda expression

    var userInput = "title";
    
    client.Search<Question>(s => s
        .Index(Meetup.DefaultIndex)
        .Query(q => q
            .Match(m => m
                .Field(f => f.Title)
                .Query("Elasticsearch Kibana")
            )
        )
        .Sort(ss => ss
            .Field(f =>
            {
                f.Order(Nest.SortOrder.Ascending);
    
                switch (userInput)
                {
                    case "body":
                        f.Field(ff => ff.Body);
                        break;
                    case "title":
                        f.Field(ff => ff.Title);
                        break;
                    default:
                        f.Field("_score");
                        f.Descending();
                        break;
                }
    
                return f;           
            })
        )
    );
    

    You may want to factor this out into a method so that the fluent method call doesn't grow unwieldy

    client.Search<Question>(s => s
        .Index(Meetup.DefaultIndex)
        .Query(q => q
            .Match(m => m
                .Field(f => f.Title)
                .Query("Elasticsearch Kibana")
            )
        )
        .Sort(ss => ss
            .Field(f => SortFromUserInput(f, userInput))
        )
    );
    
    private IFieldSort SortFromUserInput(SortFieldDescriptor<Question> f, string userInput)
    {
        f.Order(Nest.SortOrder.Ascending);
    
        switch (userInput)
        {
            case "body":
                f.Field(ff => ff.Body);
                break;
            case "title":
                f.Field(ff => ff.Title);
                break;
            default:
                f.Field("_score");
                f.Descending();
                break;
        }
    
        return f;
    }