c# - 如何在一个 Nest 查询中根据条件获取范围大于或小于?

标签 c# asp.net-core nest

我需要编写一个具有不同条件基础的范围查询

await _elasticClient.SearchAsync<T>(s => s
                            .Index(IndexName)
                            .From(From)
                            .Size(Size)
                            .Aggregations(ag => ag
                               .Cardinality("SumName", ca => ca.Field("CardinalField")))
                            .Query(q => q
                                .Bool(b => b
                                    .Must(m => m
                                            .QueryString(qs => qs                                                        .Fields("FieldNames").Query("FieldValue")),
                                          m => m.Terms(tf => tf
                                                       .Field("TermField")
                                                       .Terms("TermFeildVal")),
                                          m => m.Range(ra => ra.Field("RangeField").GreaterThanOrEquals("RangeVal")))))
                            ).ConfigureAwait(false);

如何根据输入字符串使用 GreaterThanOrEquals、GreaterThan、LessThanOrEquals 和 GreaterThan,例如,如果有人想要 gte,请使用 GreaterThanOrEquals,如果他们想要 lte,请使用 LessThanOrEquals 等?

喜欢

await _elasticClient.SearchAsync<T>(s => s
                            .Index(objFeasibilityRangeVM.IndexName)
                            .From(objFeasibilityRangeVM.From)
                            .Size(objFeasibilityRangeVM.Size)
                            .Aggregations(ag => ag
                               .Cardinality(objFeasibilityRangeVM.SumName, ca => ca.Field(objFeasibilityRangeVM.CardinalField)))
                            .Query(q => q
                                .Bool(b => b
                                    .Must(m => m
                                            .QueryString(qs => qs
                                                        .Fields(objFeasibilityRangeVM.FieldNames).Query(objFeasibilityRangeVM.FieldValue)),
                                          m => m.Terms(tf => tf
                                                       .Field(objFeasibilityRangeVM.TermField)
                                                       .Terms(objFeasibilityRangeVM.TermFeildVal)),
                                          m => m.Range(ra => ra.Field(objFeasibilityRangeVM.RangeField)
                                          FieldValue == "gte"?
                                          .GreaterThanOrEquals(RangeVal)
                                          : .LessThanOrEquals(RangeVal)
                                          ))))
                            ).ConfigureAwait(false);

最佳答案

一种选择可能是将范围部分移动到这样的方法中

QueryContainer Range(string condition)
{
    return condition == "gte" 
        ? new NumericRangeQuery { Field = "RangeField", GreaterThanOrEqualTo = 1 }
        : new NumericRangeQuery { Field = "RangeField", LessThanOrEqualTo = 1 };
}

然后你的查询就会变成这样

await _elasticClient.SearchAsync<T>(s => s
    .Index(IndexName)
    .From(From)
    .Size(Size)
    .Aggregations(ag => ag
        .Cardinality("SumName", ca => ca.Field("CardinalField")))
    .Query(q => q
        .Bool(b => b
            .Must(m => m
                    .QueryString(qs => qs.Fields("FieldNames").Query("FieldValue")),
                m => m.Terms(tf => tf
                    .Field("TermField")
                    .Terms("TermFeildVal")),
                _ => Range("gte"))))
).ConfigureAwait(false);

有了第二个想法,您可以使用如下事实内联您的逻辑:如果 to/from 值为 null NEST 将忽略这些值在生成的 Elasticsearch 查询中

var searchResponse = await client.SearchAsync<object>(s => s
    .Index("test")
    .From(0)
    .Size(10)
    .Aggregations(ag => ag
        .Cardinality("SumName", ca => ca.Field("CardinalField")))
    .Query(q => q
        .Bool(b => b
            .Must(m => m
                    .QueryString(qs => qs.Fields("FieldNames").Query("FieldValue")),
                m => m.Terms(tf => tf
                    .Field("TermField")
                    .Terms("TermFeildVal")),
                m =>
                {
                    double? gtValue = null;
                    double? ltValue = null;

                    if (FieldValue == "gte")
                    {
                        gtValue = 1;
                    }

                    if (FieldValue == "lte")
                    {
                        ltValue = 2;
                    }
                    
                    return m.Range(ra => ra.Field("RangeField").LessThanOrEquals(ltValue).GreaterThanOrEquals(gtValue));
                })))
);

关于c# - 如何在一个 Nest 查询中根据条件获取范围大于或小于?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/73486769/

相关文章:

c# - ASP.net 核心路由/prod/1/review/1

c# - Asp.Net Core Web API 2.2 Controller 不返回完整的 JSON

.net - 如何在NEST中的Unix时间范围内进行搜索?

c# - 继承 Progressbar 的 Value 属性如何替换?

c# - 如何填充 ASPxComboBox?

asp.net-core - 如何在 EF .NET Core 中的 [AllowAnonymous] 端点上读取 JWT token

elasticsearch - 使用 Nest Client 在 Elasticsearch 中加载完成字段

c# - Elasticsearch 和 NEST : How do you purge all documents from an index?

C# - 如何返回基于字符串的类型

c# - GUI 事件是否有可能中断 GUI 线程的运行代码以执行其自己的事件处理程序方法?