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

时间:2018-01-25 12:35:28

标签: c# sorting elasticsearch nest elasticsearch-5

我正在使用带有Nest 5.6的弹性搜索,我想只过滤100个分数最高然后按任何其他字段排序的文档。问题是分数是在分数和字段之间一起完成的,但我只想对具有最高分数的TOP(N)记录进行排序。 例如,按分数排序和项目的较低值会产生下表:

  • 得分 | 项目值
  • 0.8 | 7.0
  • 0.8 | 8.0
  • 0.7 | 6.0 - 这个价格成为第一个。

我的查询如下:

 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())
          ));

任何人对如何解决这个问题都有任何想法?

1 个答案:

答案 0 :(得分:1)

我最近自己遇到了这个问题。以下是您遇到的问题:

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

这就是我最终做的事情 - 请记住,这并不准确,因为据我所知,这并不是一个很好的方法。< / p>

使用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名。然后再将结果排在内存中。