Elasticsearch - 按分数过滤前 N 个文档,然后按字段排序

Elastic Seach - filter top N documents by score and then sort by field

我将 Elastic Search 与 Nest 5.6 一起使用,我只想筛选得分最高的 100 个文档 ,然后 按任何其他字段排序。问题是排序是在分数和字段之间一起完成的,但我只想对得分最高的 TOP (N) 记录进行排序。 例如,按分数和项目的较低值排序会导致下面的 table:

我的查询如下:

 client.Search<ItemDto>(s => s
           .From(0)
           .Size(100)
           .Index(INDEX)
           .Query(q => q                        
              .Bool(b => b.Must(query)))
          .Sort(y=>y
            .Descending(SortSpecialField.Score)
            .Field(f=>f.Field(new Field("itemValue")).Ascending())
          ));

有人知道如何解决这个问题吗?

我自己最近也遇到了这个问题。这是您 运行 遇到的问题:

分片:每个索引都由一定数量的分片组成,帮助您跨节点分布索引。但这也意味着在管道中间获取任何东西的精确计数是非常冒险的。这就是分桶聚合只为您提供最佳结果的近似值的原因。 运行针对分片单独进行计算并智能地组合它们。

这就是我最终所做的——请记住,这不会是准确的,因为据我所知,并没有真正好的方法来做到这一点。

使用 Sampler Aggregation 拉出(大约)前 100 个。您将指定分片大小为返回的结果数除以分片数。假设您有 5 个分片(默认),您从每个分片请求 20 个文档。

然后在该采样器聚合中,您可以添加一个 Top Hits Aggregation 以实际获取您的源文档并根据需要对它们进行排序。

new SamplerAggregation("sampler_aggregation")
{
    ShardSize = maxResults / SHARD_NUMBER,
    Aggregations = new TopHitsAggregation("top_hits")
    {
        Sort = {Whatever},
        Size = maxResults
    }
}

然后访问您的文档

searchResponse.Aggs.Sampler("sampler_aggregation")
                   .TopHits("top_hits")
                   .Documents<YourType>().ToArray()

但是:如果您非常希望获得非常精确的结果,那么最好只按相关性排序并抓住前 100 个。然后在内存中再次对结果进行排序。