弹性嵌套将动态值传递给排序

时间:2018-02-09 09:12:19

标签: c# elasticsearch nest

我的My Elastic Query运行良好,我有聚合,我对特定字段进行排序,但如果用户想要在价格上对其进行排序,我该如何动态更改排序字段,而无需输入switch语句围绕整个查询选择一个不同的字段。

我当前的查询:

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

2 个答案:

答案 0 :(得分:3)

您可以在Field lambda表达式

中执行此操作
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;           
        })
    )
);

您可能希望将此分解为方法,以便流畅的方法调用不会变得笨拙

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;
}

答案 1 :(得分:0)

我发现使用NEST编写模块化查询的最佳方法是使用Object Initializer语法。您可以根据需要逐个构建查询,并根据需要交换部件。

// Can write your switch statement around just this part and even wrap it in a method
var sort = new List <ISort>
{
    new SortField 
    {
        Field = Infer<YourType>(t => t.DispatchTimeInDays),
        Order = Nest.SortOrder.Ascending
    }
};

var searchRequest = new SearchRequest(typeof(YourType))
{
    Sort = sort
    // other query details omitted
};

_client.Search<YourType>(searchRequest);