【问题标题】:Elasticsearch: how to get the top unique values of a field sorted by matching score?Elasticsearch:如何获取按匹配分数排序的字段的最高唯一值?
【发布时间】:2018-11-14 01:27:57
【问题描述】:

我有一组地址。让我们简化并说唯一的字段是postcodecitystreetstreetnumbername。 当用户输入邮政编码、城市和一些街道查询时,我希望能够建议街道列表。

例如,如果用户在 HTML 表单中输入:

postcode: 75010
city: Paris
street: rue des

我想要一个街道列表

'rue des petites écuries'
'rue des messageries'
...
'rue du faubourg poissonnière'
...

我可以向用户建议。

所以,我想获取“street”字段的唯一值列表,根据它们与我在“street”字段上的查询的匹配程度进行排序。我想获得此查询的 10 条最佳匹配街道。

返回文档的查询如下所示:

{
    "query": {
        "bool": {
            "must": [
                {{"term": {"postcode": "75010"}},
                {{"term": {city": "Paris"}},
                {{"match": {"street": "rue des"}}
            ]    
        }
     }
}

当然,同一条街道会出现多次,因为每条街道可以在集合中的不同地址出现多次。

我尝试使用“聚合”框架并添加了一个 aggs:

{
    "query": {
        "bool": {
            "must": [
                {{"term": {"postcode": "75010"}},
                    {{"term": {city": "Paris"}},
                    {{"match": {"street": "rue des"}}
            ]    
        }
     },
     "aggs": {
        "street_agg": {
            "terms": {
                "field": "street",
                "size": 10
             }
         }           
     }
}

问题是它是自动排序的,不是根据分数,而是根据每个桶的文档数。

我希望根据每个存储桶中选择的任意文档的分数对存储桶进行排序(是的,从存储桶中的单个文档中获取分数就足够了,因为分数仅取决于街道的内容我的示例中的字段)。

您将如何实现这一目标?

【问题讨论】:

    标签: sorting elasticsearch unique distinct distinct-values


    【解决方案1】:

    好的,所以实际上可以在 Elasticsearch aggregation order by top hit score 中找到解决方案,但前提是您阅读了 Shadocko 的评论:Elasticsearch aggregation order by top hit score,而我没有。

    因此,对于任何感兴趣的人和我未来的自己来说,这里都是解决方案:

    {                                 
        'query': {
            'bool': {
                'must': [
                    {'term': {'postcode': '75010'}},
                    {'term': {'city': 'Paris'}},
                    {'match': {'street.autocomplete': 'rue des'}}
                ]
             }
        },
        'aggs': {
            'street_agg': {
                'terms': {
                    'field': 'street',
                    'size': 10,
                    'order': {
                        'max_score': 'desc'
                    }
                },
                'aggs': {
                    'max_score': {
                        'max': {'script': '_score'}
                    }
                }
            }
        }
    }
    

    它并不完美,因为它使用了max 聚合函数,这意味着它会进行不必要的计算(只需从存储桶中取出一个文档的分数就足够了)。但是好像没有“pick one”聚合函数,只有minmaxavgsum,所以你必须这样做。好吧,我认为无论如何计算最大值并不是那么昂贵。

    【讨论】:

      猜你喜欢
      • 2018-12-10
      • 2018-02-12
      • 1970-01-01
      • 1970-01-01
      • 2014-11-30
      • 2017-06-02
      • 2021-05-15
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多