【问题标题】:How to sort before aggregation in Elasticsearch?如何在 Elasticsearch 中聚合之前进行排序?
【发布时间】:2021-08-13 16:12:48
【问题描述】:

我有一个像这样结构的 Elasticsearch 索引

{
    "mappings": {
        "properties": {
            "content": {
                "type": "text",
                "fields":{
                    "keyword":{
                        "type":"keyword",
                        "ignore_above":20
                    }
                }
            },
            "result_nums":{
                "type":"integer"
            }
        }
    }
}

以及索引中的所有文档都像这样

{
  "content": "this",
  "result_nums": 40
},
{
  "content": "this",
  "result_nums": 40
},
{
  "content": "that",
  "result_nums": 40
},
{
  "content": "what",
  "result_nums": 50
},
{
  "content": "what",
  "result_nums": 50
},
{
  "content": "but",
  "result_nums": 100
},
{
  "content": "like",
  "result_nums": 20
}

我需要获取数据,按result_numsDESC 排序并删除重复的“内容”。例如,我使用这样的查询来获取前两个数据

{
    "size": 0,
    "aggs": {
        "content": {
            "terms": {
                "field": "content.keyword",
                "size": 2
            },
            "aggs": {
                "res_nums": {
                    "avg": {
                        "field": "result_nums"
                    }
                },
                "res_sort": {
                    "bucket_sort": {
                        "sort": [
                            {
                                "res_nums": "desc"
                            }
                        ]
                    }
                }
            }
        }
    }
}

我期望得到的数据是

                {
                    "key": "but",
                    "doc_count": 1,
                    "res_nums": {
                        "value": 100.0
                    }
                },
                {
                    "key": "what",
                    "doc_count": 2,
                    "res_nums": {
                        "value": 50.0
                    }
                }

但我真正得到的是

                {
                    "key": "what",
                    "doc_count": 2,
                    "res_nums": {
                        "value": 50.0
                    }
                },
                {
                    "key": "this",
                    "doc_count": 2,
                    "res_nums": {
                        "value": 40.0
                    }
                }

所以我认为es需要在聚合前排序,因为现在只会在聚合后排序,所以得到的结果与预期不符。

我尝试在聚合之前使用sort但没有效果

{
"size": 0,
    "sort": [
        {
            "result_nums": "desc"
        }
    ],
    "aggs": {
    ...
    }
...
}

那么如何在聚合之前进行排序呢?

【问题讨论】:

  • 在应用聚合之前,您的匹配查询已经按分数排序。这有什么好的用例?
  • 你好,我刚刚添加了我的问题的内容,你能帮我看看吗?非常感谢。
  • @dengbuqi 文档"content": "what" 在哪里,您如何在预期结果中获得what
  • 对不起,我的问题内容有一些错误,现在我已经更正了。另外,我举的数据只是为了描述我遇到的情况。如果你使用我的数据,你可能不会得到和我一样的结果。
  • 是的@dengbuqi,当我使用您更新的数据时,使用您在上述问题中提供的相同搜索查询,我得到了您期望得到的结果

标签: elasticsearch elastic-stack aggregation


【解决方案1】:

您需要使用max aggregationterm query 来获取数据,按result_nums DESC 排序并删除重复的“内容”

添加一个工作示例

搜索查询:

{
  "size": 0,
  "aggs": {
    "content": {
      "terms": {
        "field": "content.keyword",
        "order": {
          "max_num": "desc"
        },
        "size":2
      },
      "aggs": {
        "max_num": {
          "max": {
            "field": "result_nums"
          }
        }
      }
    }
  }
}

搜索结果:

"aggregations": {
    "content": {
      "doc_count_error_upper_bound": 0,
      "sum_other_doc_count": 4,
      "buckets": [
        {
          "key": "but",
          "doc_count": 1,
          "max_num": {
            "value": 100.0
          }
        },
        {
          "key": "what",
          "doc_count": 2,
          "max_num": {
            "value": 50.0
          }
        }
      ]
    }

【讨论】:

  • 太棒了!这就是我想要的,非常感谢!
猜你喜欢
  • 2016-03-15
  • 2019-04-02
  • 2015-08-25
  • 2018-04-20
  • 2016-09-08
  • 2015-01-23
  • 2021-02-11
  • 2016-04-12
  • 2022-01-26
相关资源
最近更新 更多