【问题标题】:Elasticsearch 6.2.4: how to order aggregation results by _score?Elasticsearch 6.2.4:如何按 _score 对聚合结果进行排序?
【发布时间】:2019-04-02 04:48:30
【问题描述】:

我在按_score desc 排序的查询部分得到了想要的查询结果。现在我需要提取每个文档的 3 个字段。我想达到这样的目标:

select distinct field1, field2, field3 from table A;

我刚试过:

1) 使用collapse去除重复值

GET index/_search
{
  "collapse" : {
        "field" : "filed1.keyword" 
    }
  ...
}

但问题是它只会保留filed1 的不同值,而忽略field2 和fiel3 的值。例如,我们有 2 条记录,例如:

[1, "a", "b"], [1, "c", "d"] 

使用这种方法我们只能得到一条记录,因为它们具有相同的 field1 值。我想要这三个字段的不同组合值。我们可以使用 inner_hits 来获取第二个字段的 distict 值,但是根据https://www.elastic.co/guide/en/elasticsearch/reference/current/search-request-collapse.html:第二级折叠不允许inner_hits。这意味着它不能应用于获取多个字段之间的 dicttinct 值 (>2)。

2) 使用聚合:

GET index/_search
{
  "aggs": {
    "field1": {
      "terms": {
        "field": "field1.keyword"
      },
      "aggs": {
        "field2": {
          "terms": {
            "field": field2.keyword",
            "missing": ""
          },
          "aggs": {
            "field3": {
              "terms": {
                "field": "field3.keyword",
                "missing": ""
              }
            }
          }
        }
      }
    }
  },
  ...
}

它返回 [field1, field2, field3] 的不同值,但文档的顺序发生了变化。它们是按 doc_count 而不是 _score 排序的,我们无法在结果中获取 _score 的信息。

那么我们如何在不改变当前顺序的情况下获得不同的组合值(因为我们已经在“查询”部分自定义了文档顺序)?或者我们如何按_score对聚合结果排序?

谢谢!

【问题讨论】:

    标签: elasticsearch


    【解决方案1】:

    下面是示例查询,说明您如何将aggregations 用于_score。

    POST <your_index_name>/_search
    {
      "query": {
        "match": {
          "<yourfield>": "<yourquery>"
        }
      },
      "aggs": {
        "myaggs": {
          "terms": {
            "script": "_score"
          }
        }
      }
    }
    

    因此您的上述聚合查询将采用以下形式:

    POST <your_index_name>/_search
    {  
       "size":0,
       "query":{  
          "match":{  
             "field1": "search non-search"
          }
       },
       "aggs":{  
          "myaggs":{  
             "terms":{  
                "field":"field1.keyword",
                "order": {
                  "_term": "asc"
                }
             },
             "aggs":{  
                "myotheraggs":{  
                   "terms":{  
                      "field":"field2.keyword",
                      "order": {
                        "_term": "asc"
                      }
                   },
                   "aggs":{  
                      "myotheraggs2":{  
                         "terms":{  
                           "field":"field3.keyword",
                           "order": {
                              "_term": "asc"
                           }
                         },
                         "aggs":{  
                            "myscoreaggs":{  
                               "terms":{  
                                  "script":"_score",
                                  "order": {
                                      "_term": "desc"
                                  }
                               }
                            }
                         }
                      }
                   }
                }
             }
          }
    
       }
    }
    

    因此,基本上,上述查询将按field1 field2 field3 score 的顺序返回您,其中field1 field2 field3 将根据asc lexicographical 顺序排序,而_score 将按desc 顺序排序

    例如下面是示例排序数据的显示方式

    field1|field2|field3|score
    --------------------------------
    non-search|lucene|graphdb|1
    search|lucene|elasticsearch|2
    search|lucene|elasticsearch|1
    search|lucene|solr|2
    search|lucene|solr|1
    

    更新了答案帖子聊天

    POST someindex/_search
    {  
       "size":0,
       "aggs":{  
          "myagg":{  
             "terms":{  
                "script":{  
                   "source":"doc['field1'].value + params.param + doc['field2'].value + params.param + doc['field3'].value",
                   "lang":"painless",
                   "params":{  
                      "param":", "
                   }
                },
                "order":{  
                   "_term":"asc"
                }
             }
          }
       }
    }
    

    如果有帮助,请告诉我。

    【讨论】:

    • 感谢卡马尔的回答。虽然问题是,按 _score 排序应该是优先级,因为最相关的结果应该在顶部。受这个答案的启发,我尝试将“myscoreaggs”作为父聚合,以便它以 _score 作为优先级聚合。但问题是,我在不同的存储桶中得到了重复的 `[field1, field2, fiel3]` 值,奇怪的是它们有不同的 _score。你能帮忙吗?
    • @Elva 分数由上述查询顶部的match 部分计算得出。是的,如果您按/汇总分数排序,则会出现重复,因为可能有两个文档,比如nike,但在其中一个文档中它出现了很多次,而在另一个文档中它只出现了一次。通常,搜索应用程序在实际搜索结果中具有查询结果,而您的方面/改进将是聚合结果。聚合与相关性无关。它是一个不同的概念。我建议你重新审视你的设计。如果您有任何进一步的疑问,很高兴为您提供帮助。
    • 为each 文档计算分数,each 文档可能有不同的分数。因此,当您按分数创建聚合时,您最终会得到重复的 field1 field2 field3 但不同的 score。
    • 感谢文档分数的解释--您的意思是索引中的其他字段会影响文档的分数吗?在查询中,我只使用 match/query_string/term 在三个字段中进行搜索:field1, field2 and field3 因为我只关心 3 个字段的搜索结果。在这种情况下,一个关键词出现在其他字段(3个字段除外)的次数会影响文档的最终得分吗?
    • @Elva 您现在可以检查答案吗?我已在 Updated Answer Post Chat 部分进行了更新
    猜你喜欢
    • 2019-07-12
    • 1970-01-01
    • 2014-12-24
    • 2021-09-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-10-12
    相关资源
    最近更新 更多