在ElasticSearch中按多个字段排序C#

olhwl3o2  于 5个月前  发布在  ElasticSearch
关注(0)|答案(1)|浏览(41)

我想通过rank_tx Desc排序我的响应,然后是_score Desc。目前,我只能通过rank_tx_score进行排序。
.csproj

<Project Sdk="Microsoft.NET.Sdk.Web">

    <PropertyGroup>
        <TargetFramework>net7.0</TargetFramework>
    .........
    </PropertyGroup>

    <ItemGroup>
        <PackageReference Include="Elastic.Clients.Elasticsearch" Version="8.9.1" /
    ........

字符串
C#代码

var response = await _client.SearchAsync<Model>(search =>
{
    search.Index(_indexOptions.Index)
         .Query(q => q
            .Bool(b => b
                .Should(
                    sh => sh.MatchPhrasePrefix(m => m.Field(f => f.field1).Query(input)),
                    sh => sh.MatchPhrase(m => m.Field(f => f.field1).Query(input).Slop(50))
                )
            )
         )
        .Size(50)
        .Sort(s => s
             .Field(Infer.Field<Model>(f => f.rank_tx), fs => fs.Order(SortOrder.Desc)))
        .Highlight(highlightOptions);
}, cancellationToken);


这个工作在控制台上很好。

GET /my_index/_search
{
  "query": {
    "bool": {
      "should": [
        {
          "match_phrase_prefix": {
            "my_field_1": {
              "query": input
            }
          }
        },
        {
          "match_phrase": {
            "my_field_2": {
              "query": input,
              "slop": 50
            }
          }
        }
      ]
    }
  },
  "sort": [
    { "rank_tx": { "order": "desc" } },
    { "_score": { "order": "desc" } }
  ],
  "size": 50
}


我看了官方文件,也找不到解决办法。
这些修复不起作用:
1.在sort中增加了两个sort字段

.Sort(s => s
      .Field(Infer.Field<Model>(f => f.rank_tx), fs => fs.Order(SortOrder.Desc))
      .Field("_score", fs => fs.Order(SortOrder.Desc)))


1.使用的SortOptionsDescriptor

var sortFields = new SortOptionsDescriptor<Model>()
            .Field(Infer.Field<Model>(f => f.rank_tx), fs => fs.Order(SortOrder.Desc))
            .Field("_score", fs => fs.Order(SortOrder.Desc));

.Sort(sortFields)


在这两种情况下,我得到的响应都按_score排序,这意味着它只考虑最后一个字段。

hpcdzsge

hpcdzsge1#

问题

在这两个修复中,我重新配置了相同的SortOptionsDescriptor,这就是为什么只有最后一个调用应用于最终对象。

.Sort(s => s
      .Field(Infer.Field<Model>(f => f.rank_tx), fs => fs.Order(SortOrder.Desc))
      .Field("_score", fs => fs.Order(SortOrder.Desc)))

个字符

解决方案

存在接受params Action<SortOptionsDescriptor<TDocument>>[]的排序重载

var response = await _client.SearchAsync<Model>(search =>
{
    search.Index(_indexOptions.Index)
         .Query(q => q
            .Bool(b => b
                .Should(
                    sh => sh.MatchPhrasePrefix(m => m.Field(f => f.field1).Query(input)),
                    sh => sh.MatchPhrase(m => m.Field(f => f.field1).Query(input).Slop(50))
                )
            )
         )
        .Size(50)
        .Sort(
            s => s.Field(Infer.Field<Model>(f => f.rank_tx), fs => fs.Order(SortOrder.Desc)),
            s => s.Field("_score", fs => fs.Order(SortOrder.Desc)))
        .Highlight(highlightOptions);
}, cancellationToken);

相关问题