如何根据ElasticSearchdsl的范围/过滤器进行优先级排序,以便可以过滤列表,先显示可用性>60%,然后<

8wigbo56  于 2021-06-15  发布在  ElasticSearch
关注(0)|答案(1)|浏览(360)

申请人的相关性需要根据当月的可用性%进行排序。首先,可用率超过60%的申请人应该来,然后可用率低于60%的申请人应该来。
我正在尝试使用的fluent dsl查询使用elasticsearch.net

var response = await 
_elasticClient.SearchAsync<ApplicantsWithDetailsResponse>(s =>
                             s.Aggregations(a => a

.Filter("higer_average", f => f.Filter(fd => fd.Range(r => r.Field(p 
=> p.AvailablePercentage).GreaterThanOrEquals(60).Boost(5))))

.Filter("lower_average", f => f.Filter(fd => fd.Range(r => r.Field(p 
=> p.AvailablePercentage).GreaterThan(0).LessThan(60).Boost(3)))
                             )));

或者

var response = await _elasticClient.SearchAsync<ApplicantsWithDetailsResponse>(
        s => s
          .Query(q => q
           .Bool(p =>
                    p.Must(queryFilter => queryFilter.MatchAll())
                            .Filter(f => f.Range(r => r.Field("AvailablePercentage").GreaterThanOrEquals(60)))
                            .Boost(5)
                            .Filter(f => f.Range(r => r.Field("AvailablePercentage").GreaterThan(0).LessThan(60)))
                            .Boost(1.2)
                             )));

申请人的名单不符合逻辑。他们混合在一起。
即使我尝试过滤只显示大于60的值,这也不起作用

toiithl6

toiithl61#

你的问题不正确;它序列化为

{
  "query": {
    "bool": {
      "boost": 1.2,
      "filter": [
        {
          "range": {
            "AvailablePercentage": {
              "gt": 0.0,
              "lt": 60.0
            }
          }
        }
      ],
      "must": [
        {
          "match_all": {}
        }
      ]
    }
  }
}

升压作用于整个系统 bool 查询
最后 Filter “指定”将覆盖以前的任何筛选器
过滤器是 and 埃德,所以所有人都需要满足于比赛
在开发过程中,观察客户端发送给elasticsearch的json是很有用的。有很多方法可以做到这一点,其中一个有用的方法是

var defaultIndex = "default-index";
var pool = new SingleNodeConnectionPool(new Uri("http://localhost:9200"));

var settings = new ConnectionSettings(pool)
    .DefaultIndex(defaultIndex)
    .DisableDirectStreaming()
    .PrettyJson()
    .OnRequestCompleted(callDetails =>
    {
        if (callDetails.RequestBodyInBytes != null)
        {
            Console.WriteLine(
                $"{callDetails.HttpMethod} {callDetails.Uri} \n" +
                $"{Encoding.UTF8.GetString(callDetails.RequestBodyInBytes)}");
        }
        else
        {
            Console.WriteLine($"{callDetails.HttpMethod} {callDetails.Uri}");
        }

        Console.WriteLine();

        if (callDetails.ResponseBodyInBytes != null)
        {
            Console.WriteLine($"Status: {callDetails.HttpStatusCode}\n" +
                     $"{Encoding.UTF8.GetString(callDetails.ResponseBodyInBytes)}\n" +
                     $"{new string('-', 30)}\n");
        }
        else
        {
            Console.WriteLine($"Status: {callDetails.HttpStatusCode}\n" +
                     $"{new string('-', 30)}\n");
        }
    });

var client = new ElasticClient(settings);

这将把所有请求和响应写到控制台。请注意,您可能不希望在生产环境中为每个请求都这样做,因为以这种方式缓冲请求和响应会带来性能开销。
您的查询应该类似于

var response = client.Search<ApplicantsWithDetailsResponse>(s => s
    .Query(q => q
        .Bool(p => p
            .Must(queryFilter => queryFilter
                .MatchAll()
            )
            .Should(f => f
                .Range(r => r
                    .Field("AvailablePercentage")
                    .GreaterThanOrEquals(60)
                    .Boost(5)
                ), f => f
                .Range(r => r
                    .Field("AvailablePercentage")
                    .GreaterThan(0)
                    .LessThan(60)
                    .Boost(1.2)
                )
            )
            .MinimumShouldMatch(1)
        )
    )
);

它发出以下查询

{
  "query": {
    "bool": {
      "minimum_should_match": 1,
      "must": [
        {
          "match_all": {}
        }
      ],
      "should": [
        {
          "range": {
            "AvailablePercentage": {
              "boost": 5.0,
              "gte": 60.0
            }
          }
        },
        {
          "range": {
            "AvailablePercentage": {
              "boost": 1.2,
              "gt": 0.0,
              "lt": 60.0
            }
          }
        }
      ]
    }
  }
}

将范围查询与 should 子句,并指定至少有一个必须与using匹配 MinimumShouldMatch . 这是必要的,因为存在 must 子句,这意味着 should 从句对文档起到增强信号的作用,但是文档不必满足任何一个从句就可以被认为是匹配的。与 MinimumShouldMatch 设置为1时,至少有一个 should 条款必须满足才能被视为匹配。
自从 must 子句是 match_all 在这种情况下,我们可以省略它并删除它 MinimumShouldMatch . 一 should 不带a的子句 must 子句表示至少有一个子句必须匹配。
为了简洁起见,我们还可以使用操作符重载来组合查询。最后的查询看起来像

var response = client.Search<ApplicantsWithDetailsResponse>(s => s
    .Query(q => q
        .Range(r => r
            .Field("AvailablePercentage")
            .GreaterThanOrEquals(60)
            .Boost(5)
        ) || q
        .Range(r => r
            .Field("AvailablePercentage")
            .GreaterThan(0)
            .LessThan(60)
            .Boost(1.2)
        )
    )
);

它发出查询

{
  "query": {
    "bool": {
      "should": [
        {
          "range": {
            "AvailablePercentage": {
              "boost": 5.0,
              "gte": 60.0
            }
          }
        },
        {
          "range": {
            "AvailablePercentage": {
              "boost": 1.2,
              "gt": 0.0,
              "lt": 60.0
            }
          }
        }
      ]
    }
  }
}

相关问题