Elasticsearch 中的多个分组依据

2024-01-12

我需要使用 ES 中的 3 个字段进行聚合(分组)。

我可以在 1 个查询中执行此操作,还是需要对每一列使用构面 + 迭代?

谢谢


从1.0版本开始ElasticSearch, 新的聚合 API http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/search-aggregations.html允许按多个字段分组,使用子聚合。假设你想按字段分组field1, field2 and field3:

{
  "aggs": {
    "agg1": {
      "terms": {
        "field": "field1"
      },
      "aggs": {
        "agg2": {
          "terms": {
            "field": "field2"
          },
          "aggs": {
            "agg3": {
              "terms": {
                "field": "field3"
              }
            }
          }          
        }
      }
    }
  }
}

当然,这可以适用于您想要的任意多个领域。

Update:
为了完整起见,以下是上述查询的输出。下面还有用于生成聚合查询并将结果展平到字典列表中的 python 代码。

{
  "aggregations": {
    "agg1": {
      "buckets": [{
        "doc_count": <count>,
        "key": <value of field1>,
        "agg2": {
          "buckets": [{
            "doc_count": <count>,
            "key": <value of field2>,
            "agg3": {
              "buckets": [{
                "doc_count": <count>,
                "key": <value of field3>
              },
              {
                "doc_count": <count>,
                "key": <value of field3>
              }, ...
              ]
            },
            {
            "doc_count": <count>,
            "key": <value of field2>,
            "agg3": {
              "buckets": [{
                "doc_count": <count>,
                "key": <value of field3>
              },
              {
                "doc_count": <count>,
                "key": <value of field3>
              }, ...
              ]
            }, ...
          ]
        },
        {
        "doc_count": <count>,
        "key": <value of field1>,
        "agg2": {
          "buckets": [{
            "doc_count": <count>,
            "key": <value of field2>,
            "agg3": {
              "buckets": [{
                "doc_count": <count>,
                "key": <value of field3>
              },
              {
                "doc_count": <count>,
                "key": <value of field3>
              }, ...
              ]
            },
            {
            "doc_count": <count>,
            "key": <value of field2>,
            "agg3": {
              "buckets": [{
                "doc_count": <count>,
                "key": <value of field3>
              },
              {
                "doc_count": <count>,
                "key": <value of field3>
              }, ...
              ]
            }, ...
          ]
        }, ...
      ]
    }
  }
}

以下 python 代码根据给定的字段列表执行分组。我你指定include_missing=True,它还包括一些缺少某些字段的值的组合(如果您有 Elasticsearch 2.0 版本,则不需要它,这要归功于this https://github.com/elastic/elasticsearch/pull/11042)

def group_by(es, fields, include_missing):
    current_level_terms = {'terms': {'field': fields[0]}}
    agg_spec = {fields[0]: current_level_terms}

    if include_missing:
        current_level_missing = {'missing': {'field': fields[0]}}
        agg_spec[fields[0] + '_missing'] = current_level_missing

    for field in fields[1:]:
        next_level_terms = {'terms': {'field': field}}
        current_level_terms['aggs'] = {
            field: next_level_terms,
        }

        if include_missing:
            next_level_missing = {'missing': {'field': field}}
            current_level_terms['aggs'][field + '_missing'] = next_level_missing
            current_level_missing['aggs'] = {
                field: next_level_terms,
                field + '_missing': next_level_missing,
            }
            current_level_missing = next_level_missing

        current_level_terms = next_level_terms

    agg_result = es.search(body={'aggs': agg_spec})['aggregations']
    return get_docs_from_agg_result(agg_result, fields, include_missing)


def get_docs_from_agg_result(agg_result, fields, include_missing):
    current_field = fields[0]
    buckets = agg_result[current_field]['buckets']
    if include_missing:
        buckets.append(agg_result[(current_field + '_missing')])

    if len(fields) == 1:
        return [
            {
                current_field: bucket.get('key'),
                'doc_count': bucket['doc_count'],
            }
            for bucket in buckets if bucket['doc_count'] > 0
        ]

    result = []
    for bucket in buckets:
        records = get_docs_from_agg_result(bucket, fields[1:], include_missing)
        value = bucket.get('key')
        for record in records:
            record[current_field] = value
        result.extend(records)

    return result
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Elasticsearch 中的多个分组依据 的相关文章

随机推荐

  • 如何在 PHP 中合并两个 JSON 字符串?

    我有两个像这样的 JSON 字符串 json1 src 1 order 2 src 10 order 20 and json2 src 4 order 5 src 6 order 7 我正在尝试用它来合并它们 images array me
  • 警告:“尝试更改冻结标题”

    我们的网站 www seeing org 最近更改了其标题 我们还决定增加其 Facebook 集成 包括利用以下对象属性og title 但是 在调试页面时 我收到以下警告 应修复的开放图警告 尝试冻结标题 改变 看来您正在尝试更改属性
  • 如何防止恶意使用我的套接字?

    我正在制作一个基于玩家能够邀请其他玩家参加聚会的网页 以及其他需要等待的事情 我有你们队伍中聊天 用户的基本发送 接收 更新 唯一的问题是 如何阻止某人坐在那里打开开发者控制台并继续 socket emit updateUsers Wein
  • Python 3.2 空闲与终端

    在 OSX 下的 python 3 2 中 如果我在 Idle 下运行 type sys stdin 我会得到一个奇怪的答案 如下所示 gt gt gt type sys stdin
  • 从 AVPlayer 中当前播放的视频中录制流音频

    很多类似的问题 但并不完全相同 我目前的代码设置是通过 AVPlayer 播放视频 我想要做的是以某种方式提取流视频的音频并最终与麦克风输入合并 使用 AVAudioMixer 想想卡拉 OK 应用程序 因此当用户播放录音时 它将仅播放视频
  • Express js 中允许多个 CORS 域

    如何以简化的方式允许 Express 中的 CORS 多个域 I have cors origin www one com app all function req res next res header Access Control Al
  • 如何释放 WebAssembly 中公开的 Rust 代码分配的内存?

    我有一个用 Rust 和 wasm bindgen 编写的 Web 应用程序 需要存储状态 状态存储如下 lazy static static ref ID TO DATA Mutex
  • UICollectionView PerformBatchUpdates:动画所有部分

    我正在写一个自定义UICollectionViewFlowLayout我注意到initialLayoutAttributesForAppearingItemAtIndexPath and initialLayoutAttributesFor
  • 变得致命:肮脏的存储库:有未提交的更改。使用 git ftp push 退出管道

    我有一个管道设置 可以自动处理 构建 CSS 文件 有时我在执行时会遇到此错误git ftp push 致命 肮脏的存储库 有未提交的更改 正在退出 bitbucket pipelines yml image php 7 2 7 pipel
  • 如何从 webviewclient 打开拨号器活动?

    我正在使用 webviewclient 打开 html 页面 html 页面有一个锚标记 当我单击锚标记时 应该启动我的电话拨号器活动 当我在外部浏览器 android 默认浏览器 中单击此锚标记时 它正在启动电话拨号器 但因为我正在使用
  • 在标题中使用 WordPress 短代码

    我有一些短代码可以在 WordPress 帖子或页面中正常工作 我可以在functions php中添加什么东西来使短代码能够在WordPress帖子标题中工作吗 您可以尝试在标题中添加过滤器functions php文件如 add fil
  • Control.Select() 和 Control.Focus() 有什么区别?

    在 WinForms 中 要将焦点设置到特定控件 我似乎总是最终调用Control Select and Control Focus 让它发挥作用 有什么区别 这是正确的方法吗 Focus 是实际设置焦点的低级函数 Select 是一个更高
  • 更新 Snowflake 中的混合嵌套对象

    我有一个雪花表 其中有一个变体列 raw 该表中的每一行都是复杂的 字典和数组 并且是嵌套的 多个层次结构 我想做的是能够更新specific某个数组中的项目 使用示例会更容易理解它 因此将其视为表中的一行 id 1234 x id y i
  • 最喜欢的性能调整技巧[关闭]

    就目前情况而言 这个问题不太适合我们的问答形式 我们希望答案得到事实 参考资料或专业知识的支持 但这个问题可能会引发辩论 争论 民意调查或扩展讨论 如果您觉得这个问题可以改进并可能重新开放 访问帮助中心 help reopen questi
  • RoboScript 无法在 Firebase Testlab 中单击“启用位置确定”按钮

    我正在尝试在 Firebase TestLab 上使用 RoboScript 测试基于 Google 地图的 Android 应用程序 默认情况下 TestLab 设备上禁用位置 要启用它们 我们需要模拟单击系统提示上的 确定 按钮 但这种
  • 为什么说TCP/IP协议族中的IP协议是无连接的?

    为什么IP被称为无连接协议 如果是的话 那么面向连接的协议是什么 Thanks 更新 1 20 21 2010 12 26 我认为 为了更好地回答我的问题 最好从物理上和逻辑上解释 连接 的实际含义 更新 2 9 59 AM 2 1 201
  • 如何反序列化具有重复键的 JSON 而不丢失任何值?

    我正在尝试反序列化一些具有重复键的 JSON 并且它们可能有任意数量 JSON 看起来像这样 abilities ability id 5134 ability level 3 ability id 5136 ability level 3
  • 带有自定义分隔符的 Angularjs 静态数字过滤器

    如何将 Angularjs 数字过滤器中的分隔符从逗号更改为自定义的分隔符 Now price number 回报1 000 00 我需要像这样1 000 00 我到底需要如何重写内置角度过滤器 您不必弄乱 Angular 源代码或将语言环
  • Selenium Grid 支持 Selenium 2?

    我读到计划在 2010 年年底为 Selenium 2 0 提供 Selenium Grid 支持 显然这还没有发生 有人知道这方面的任何更新吗 Selenium Grid 2 支持 Selenium 2 并向后兼容 Selenium 1
  • Elasticsearch 中的多个分组依据

    我需要使用 ES 中的 3 个字段进行聚合 分组 我可以在 1 个查询中执行此操作 还是需要对每一列使用构面 迭代 谢谢 从1 0版本开始ElasticSearch 新的聚合 API http www elasticsearch org g