当前位置: 首页 > 知识库问答 >
问题:

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

毛峻
2023-03-14

数据

我在ES索引中保留了对象。其中每个字段都有一个myKey和myName字符串字段(持久化为关键字字段)。不能保证同一个myKey的myName总是相同的。E、 g.以下两个条目共享相同的myKey,但具有不同的myName值:

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

挑战

我需要选择并返回所有不同的myKey值,查找并显示最可能的myName(myKey上下文中出现的最多),并按myName对生成的Bucket进行排序。

到目前为止,我做到了以下几点:

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

这是聚合的代码:

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

我阅读了ES文档,其中解释了如何引入返回单个度量的第二个聚合。但这似乎只针对数字字段。myName不是数字。

有没有办法按myName对ES中的存储桶进行排序?

非常感谢您的帮助。

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

很明显,桶的排序基于以下键:123asd在456fgh之前:

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

任务是根据额外选择的字段myName:英国美国之前对桶进行排序:

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

共有1个答案

浦德明
2023-03-14

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

您是否尝试过以下方法来查找给定myKey下最频繁的myNames?

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

或者您是否希望根据子myNameagg的结果对父myKeyagg进行排序?

编辑

按多桶子聚合的结果对父agg进行排序会导致以下错误:

存储桶只能在子聚合器路径上排序,该子聚合器路径由路径中的零个或多个单桶聚合和路径端的最终单桶或指标聚合构建。

换言之,您试图实现的目标是不可能的,下面很好地解释了原因。

如果您的子聚合是数字(或单个bucket),那么这是可能的。

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

 类似资料:
  • 我有一个索引,,我需要将其聚合到每年的桶中,然后进行排序。 我已经成功地使用Bucket Sort按简单的和值(

  • 我们目前正在开发一个多语言文档CMS。因此,我们有翻译成不同语言的文件。 对于使用Elasticsearch进行搜索,我们目前使用每种语言(德语、英语、法语……)一个索引,其中同一文档的所有翻译共享相同的ID。 当用户搜索特定术语时,我们希望在所有语言中搜索,但只返回不同ID的列表。据我所知,只有使用以下术语聚合才能做到这一点: 这很好,但是作为弹性搜索文档https://www.elastic.

  • 我有一个Elasticsearch文档索引,其中有一个包含URL列表的字段。如预期的那样,在该字段上聚合会给我唯一URL的计数。 然后,我想过滤掉其键不包含特定字符串的桶。我已经尝试使用Bucket选择器聚合来实现这一点。 此尝试: 失败原因: 名为[links\u key\u filter]且类型为[bucket\u selector]的管道聚合无效。顶层仅允许同级管道聚合 将bucket选择器

  • 问题内容: ES版本:1.5(Amazon Elasticsearch) 我的目标:在某个字段上具有重复数据删除功能的搜索结果。我目前正在对聚合进行一些研究,以解决重复数据删除问题。因此,我的结果是一个带有1个大小的存储桶的列表存储桶。但是,我找不到订购存储桶列表的方法。 当前查询: 结果: 我想看到第二个存储桶,其中max_score = 68.78424为第一个。这可能吗? 如果不建议使用聚合

  • 问题内容: 我正在尝试使用以下查询对以下数据进行elasticsearch来执行术语聚合,输出将名称分解为标记(请参见下面的输出)。因此,我尝试将os_name映射为multi_field,但现在无法通过它查询。是否可以有没有令牌的索引?例如“ Fedora Core”? 查询: 数据: 输出: 映射: 问题答案: 实际上,您应该像这样更改映射 并且您的aggs应该更改为:

  • 我想根据top hits聚合中第一个元素所拥有的属性,从terms聚合中订购Bucket。 我的尽力而为查询如下(有语法错误): 有人知道如何做到这一点吗? 例子: 按“a”分组,按“id”(desc)排序存储桶,并按“b”(desc)排序最热门的内容,将给出: