Elasticsearch:按非关键列对术语聚合桶进行排序

时间:2020-08-31 14:17:47

标签: elasticsearch

数据

我的对象保留在ES索引中。它们每个都有一个 myKey myName 字符串字段(一直作为关键字字段)。不能保证 myName 对于相同的 myKey 总是相同的。例如。以下两个条目共享相同的 myKey ,但具有不同的 myName 值:

{
  "myKey": "123asd",
  "myName": "United States",
  ...
},
{
  "myKey": "123asd",
  "myName": "United States of America",
  ...
},
{
  "myKey": "456fgh",
  "myName": "United Kingdom",
  ...
}

挑战

我需要选择并返回所有不同的 myKey 值,找到并显示最可能的 myName (在 myKey 内出现的次数最多的情况) ),然后按 myName 排序生成的存储桶。

到目前为止,我管理以下内容:

  1. 使用条款聚合选择不同的 myKey 值。
  2. 使用 top_hits 聚合为每个 myKey 选择对应的第一个 myName 值。
  3. myKey 使用术语聚合的order子句排序。

这是聚合的代码:

"aggs": {
"distinct": {
  "terms": {
    "field": "myKey",
    "order": {
      "_key": "desc"    <----- this sorts the buckets by myKey
    }
  },
  "aggs": {
    "tops": {
      "top_hits": {
        "size": 1,
        "_source": {
          "includes": ["myName"]
        }
      }
    }
  }
}

我读了ES documentation,解释了如何引入第二种返回单个度量的聚合。但这似乎只解决数字字段。 myName 不是数字。

是否可以通过 myName 对ES中的存储桶进行排序?

任何帮助表示赞赏。

编辑于2020年9月2日

根据用户@joe的询问,当前和预期结果如下。

当前结果

很明显,存储桶的排序基于以下关键字:123asd456fgh之前:

"aggregations" : {
  "distinct" : {
    "buckets" : [
      {
        "key" : "123asd",
        "tops" : {
          "hits" : {
            "hits" : [
              {
                "_source" : {
                  "myName" : "United States"
                }
              }
            ]
          }
        }
      },
      {
        "key" : "456fgh",
        "tops" : {
          "hits" : {
            "hits" : [
              {
                "_source" : {
                  "myName" : "United Kingdom"
                }
              }
            ]
          }
        }
      }
    ]
  }
}

预期结果

任务是根据额外选择的字段myName:United KingdomUnited States之前对存储区进行排序:

"aggregations" : {
  "distinct" : {
    "buckets" : [
      {
        "key" : "456fgh",
        "tops" : {
          "hits" : {
            "hits" : [
              {
                "_source" : {
                  "myName" : "United Kingdom"
                }
              }
            ]
          }
        }
      },
      {
        "key" : "123asd",
        "tops" : {
          "hits" : {
            "hits" : [
              {
                "_source" : {
                  "myName" : "United States"
                }
              }
            ]
          }
        }
      }
    ]
  }
}

1 个答案:

答案 0 :(得分:1)

通过执行_count:desc,您只按字母顺序排列了顶部agg ...

您是否尝试过以下操作,这些操作在给定的myName下寻找最频繁的myKey

{
  "size": 0, 
  "aggs": {
    "by_key": {
      "terms": {
        "field": "myKey",
        "order": {
          "_key": "desc"
        }
      },
      "aggs": {
        "by_name": {
          "terms": {
            "field": "myName",
            "order":{
              "_count": "desc"
            }
          }
        }
      }
    }
  }
}

还是要根据子项myKey的结果对父项myName的结果进行排序?


编辑

通过多存储桶子聚合的结果对父级agg进行排序会导致以下错误:

只能在构建的子聚合器路径上对存储桶进行排序 路径中的零个或多个单桶聚合以及最终 路径末端的单个存储桶或指标聚合。

换句话说,您要实现的目标是不可能的,这里是nicely explained why

如果您的子聚合是数字(或单桶),则应该是possible

目前,您唯一的选择似乎是在前端(或您使用这些aggs的任何地方)对当前响应进行后处理(或后排序)。

相关问题