Elasticsearch 基本使用(四)聚合查询

news2024/9/21 12:34:36

聚合查询

    • 概述
    • 单字段聚合查询
      • 统计分组后的数量
        • 非文档字段分组
        • 文档字段分组
      • 其他聚合运算
        • 统计平均值
        • 统计总金额
        • 统计最大值
        • 自定义聚合结果排序
        • 简单聚合小结
    • 多字段聚合查询

概述

说到聚合查询,马上会想到 SQL 中的 group by,ES中也有类似的功能,名叫 Aggregation。

单字段聚合查询

统计分组后的数量

按年龄分组,然后统计每个年龄人数 count(*) ,age xxx group by age

非文档字段分组

GET bank/_search
{
  "aggs": {
    "by_age": {
      "terms": {
      # age 为数值,可以直接分组
        "field": "age"
      }
    }
  }
}

文档字段分组

GET bank/_search
{
  "aggs": {
    "by_age": {
      "terms": {
        "field": "city"
      }
    }
  }
}

直接使用文档字段分组会报错。
在这里插入图片描述
ES没有对文本字段聚合,排序等操作优化;如果对文本字段进行分组,推荐使用 关键字字段
改为关键字分组

GET bank/_search
{
  "aggs": {
    "by_age": {
      "terms": {
        "field": "city.keyword"
      }
    }
  }
}

在这里插入图片描述
但是,ES默认只返回10条分组数据;如果要返回更多分组数据,需要在聚合里面使用 size 字段

GET bank/_search
{
  "aggs": {
    "by_age": {
      "terms": {
        "field": "city.keyword",
        "size": 1000
      }
    }
  }
}

可以看到,返回了更多的分组数据
在这里插入图片描述

其他聚合运算

在使用 terms时,ES会根据指定字段进行分组;此时得到的结果集是

"buckets" : [
        {
          "key" : 分组字段的值,
          "doc_count" : 当前分组数量
        }
]        

统计平均值

如果,我们要基于当前分组,进行其他聚合运算呢。
比如,我按照年龄分组,统计数量;
然后我要统计每个分组内,账户余额的平均值呢。

# 基于年龄分组的基础上,统计账户余额平均值
GET bank/_search
{
  "size": 0, 
  "aggs": {
    "by_age": {
      "terms": {
        "field": "age",
        "size": 1000
      },
      "aggs": {
        "avg_balance": {
          "avg": {
            "field": "balance"
          }
        }
      }
    }
  }
}

统计总金额

如果还要基于账户余额平均值的基础上,还要进行其他聚合运算,可以直接在 内部的 aggs 内添加其他聚合函数。比如,我不仅要统计平均值,还要统计每个分组内的账户总金额。

# 基于统计账户余额平均值的基础上,再统计每个分组下,账户总金额
GET bank/_search
{
  "size": 0, 
  "aggs": {
    "by_age": {
      "terms": {
        "field": "age",
        "size": 1000
      },
      "aggs": {
        "avg_balance": {
          "avg": {
            "field": "balance"
          }
        },
        "sum_balance":{
          "sum": {
            "field": "balance"
          }
        }
      }
    }
  }
}

统计最大值

再统计一个,基于年龄的分组下,账户余额的最大值

# 基于统计账户余额平均值和总金额的基础上,再统计每个分组下,账户最大余额
GET bank/_search
{
  "size": 0, 
  "aggs": {
    "by_age": {
      "terms": {
        "field": "age",
        "size": 1000
      },
      "aggs": {
        "avg_balance": {
          "avg": {
            "field": "balance"
          }
        },
        "sum_balance":{
          "sum": {
            "field": "balance"
          }
        },
        "max_balance":{
          "max": {
            "field": "balance"
          }
        }
      }
    }
  }
}

自定义聚合结果排序

默认,ES的聚合以分组内数量倒序排序。
我们基于上面最后的统计结果,自定义聚合结果排序

  • 默认排序方式
    在这里插入图片描述
  • 按数量升序
    之前说过,默认分组,提供了两个字段的返回;
    key 和 doc_count,如果要自定义这两个基本字段排序方式,需要在前面加上 下划线 _当然还可以按照其他聚合函数的结果排序
GET bank/_search
{
  "size": 0, 
  "aggs": {
    "by_age": {
      "terms": {
        "field": "age",
        "size": 1000,
        "order": {
        # 数量升序/降序
          "_count": "asc/desc"
          # key 升序/降序
          "_key": "asc/desc",
          # 按平均值升序/降序
          "avg_balance":"asc/desc",
          # 按总金额值升序/降序
          "sum_balance":"asc/desc",
          # 按最大值升序/降序
          "max_balance":"asc/desc",
        }
      },
      "aggs": {
        "avg_balance": {
          "avg": {
            "field": "balance"
          }
        },
        "sum_balance":{
          "sum": {
            "field": "balance"
          }
        },
        "max_balance":{
          "max": {
            "field": "balance"
          }
        }
      }
    }
  }
}

简单聚合小结

总之,一句话。
分组逻辑在外面的 aggs,使用的是 terms 指定分组字段;默认,附带每个分组内数量统计。
基于此分组的其他聚合运算,aggs 内再定义一个 aggs,用于定义其他聚合运算。
自定义聚合结果排序,在aggs -> terms 下使用 order 指定排序字段及其排序方式,但是,经过测试,直接写多个字段排序时,只有最后一个生效

多字段聚合查询

上面的聚合查询,我们都是基于一个字段进行查询。
那么如何实现按多个字段进行分组呢?

我们先看看,在上面额外聚合运算上使用 terms 的效果

  • 先对 age分组,再对gender(文档字段,需使用关键字形式)分组,看看效果
GET bank/_search
{
  "size": 0, 
  "aggs": {
    "by_age": {
      "terms": {
        "field": "age",
        "size": 1000,
        "order": {
          "_count": "desc"
        }
      },
      "aggs": {
        "by_gender":{
          "terms": {
            "field": "gender.keyword",
            "size": 1000
          }
        }
        
      }
    }
  }
}

在这里插入图片描述
可以看到,得到的结果是一个带有层级结构的数据,这在某些场景下可能有用;但常规的多字段分组可不是这样的,我们通常需要一个扁平化的排序结果

  • 使用 script 替代 field ,定义分组字段
    script :使用脚本,运算一个结果来作为分组字段。
    使用以下 脚本替代 field
    "script": {
        "inline": "doc['age'].value +'-'+ doc['gender.keyword'].value "
    }
    

以上脚本的意思是,使用 age-gender 作为分组依据,注意,这里依然要注意文档字段 .keyword 的问题,以下是完整脚本

# 按多个字段分组,这里按照 年龄-性别 分组,不能直接使用 field 分组,要使用 script 构建分组内容;按默认的数量倒序
GET bank/_search
{
  "size": 0, 
  "aggs": {
    "by_state": {
      "terms": {
        "script": {
                    "inline": "doc['age'].value +'-'+ doc['gender.keyword'].value "
                },
        "size": 1000,
        "order": {
          "_count": "desc"
        }
      },
      "aggs": {
        "avg_balance": {
          "avg": {
            "field": "balance"
          }
        },
        "sum_balance":{
          "sum": {
            "field": "balance"
          }
        },
        "max_balance":{
          "max": {
            "field": "balance"
          }
        }
      }
    }
  }
}

可以看到,按照预期进行了分组
在这里插入图片描述
至于基于分组的其他聚合运算,排序等操作,和单字段分组一样。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/659774.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

编程语言发展历史

文章目录 语言的发展时间轴语言世代时间轴1940年前-机器语言时代1940年后-汇编语言时代1950年-高级语言的初生1960年-高级语言的进一步成熟1980年-各大语言的进一步增强1990年代-飞速发展时代2000年-新时代 高级编程语言的分类解释型与编译型面向过程与面向对象 对语言的评价Ti…

【学习学习】NLP理解层次模型

NLP(Neuro-Linguistic Programming,神经语言程序学),由两位美国人理查得.班德勒(Richard Bandler)与约翰.葛瑞德(John Grinder)于1976年创办,并在企业培训中广泛使用。美…

PyTorch 深度学习 || 4. 自编码网络 | Ch4.3 卷积自编码网络图像去噪

卷积自编码网络图像去噪 1. 数据的准备 先简单介绍一下训练网络使用到的图像数据集——STL10,该数据集可以通过torchvision.datasets模块中的STL10()函数进行下载,该数据集共包含三种类型数据,分别是带有标签的训练集和验证集,分别包含5000…

Cookie增删改查方法封装(低内存开销版)

本文章中的低内存开销是指在获取cookie的时候不进行字符串—>数组的转变,全程使用sliceindexOf切割字符串,不创建和操作数组,节约内存,本文代码已存放到github中,后续会持续完善功能,传送门:…

二进制方式部署kubernetes集群

二进制方式部署kubernetes集群 1、部署k8s常见的几种方式 1.1 kubeadm Kubeadm 是一个 k8s 部署工具,提供 kubeadm init 和 kubeadm join,用于快速部署 Kubernetes 集群。 Kubeadm 降低部署门槛,但屏蔽了很多细节,遇到问题很难…

掌握Python的X篇_4_开发工具ipython与vscode的安装使用

本篇将会介绍两个工具的安装及使用来提高Python的编程效率。 ipython:比python更好用的交互式开发环境vscode:本身是文本编辑器,通过安装相关的插件vscode可以作为python集中开发环境使用 掌握Python的X篇_4_开发工具ipython与vscode的安装使…

第四章 linux编辑器——vim的使用

第四章 linux编辑器——vim的使用 一、什么是vim?二、vim的基本操作1、模式之间的相互切换2、vim的常见命令集(1)正常模式的常见命令a. 模式切换b. 光标移动c.删除文字d.复制e.替换f.撤销g.更改 (2)底行模式的常见命令…

复习之linux的网络配置

一、基本定义 1.IP IP指网际互连协议,Internet Protocol的缩写,是TCP/IP体系中的网络层协议。 电脑之间要实现网络通信,就必须要有一个合法的ip地址。 IP地址网络地址主机地址(又称:主机号和网络号组成&#xff09…

【MySQL】MyISAM中的索引方案

介绍 B树索引使用存储引擎如表所示: 索引/存储引擎MyISAMInnoDBMemoryB树索引支持支持支持 多个存储引擎支持同一种类型的索引,但是他们的实现原理是不同的。 InnoDB和MyISAM默认的索引是B树索引,而Memory默认的索引是Hash索引。 MyISAM…

【软件测试】在Windows使用Docker搭建CentOS环境(详细)

目录:导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结(尾部小惊喜) 前言 我们做软件测试在…

租服务器跑代码、pycharm连接服务器跑代码、Xshell连接服务器运行代码

一、服务器 1.1 注册 推荐使用矩池云服务器,按时按量计费,服务器自带镜像可选,可将要运行的项目上传到网盘 注册网址:矩池云 1.2 租用 选择合适的租用 1.3 选择镜像 选择合适的系统镜像 1.4 复制命令 进入租用列表&#xff…

【每日挠头算法题(9)】二叉树的直径|二叉树的层序遍历

文章目录 一、二叉树的直径思路:二叉树的深度优先搜索具体代码如下: 二、二叉树的层序遍历思路:借助队列实现具体代码如下: 总结: 一、二叉树的直径 点我直达~ 思路:二叉树的深度优先搜索 根据题目要求&a…

【计网】第三章 数据链路层

文章目录 数据链路层一、使用点对点信道的数据链路层1.1 数据链路和帧1.2 三个基本问题封装成帧透明传输差错控制 二、点对点协议 PPP2.1 PPP 协议的特点2.2 PPP 协议的帧格式2.3 PPP 协议的工作状态 三、使用广播信道的数据链路层3.1 局域网的数据链路层3.2 CSMA/CD 协议3.3 使…

安规测试简介(二)-常见安规认证测试之CE认证

CE认证: CE是法语的缩写,英文意思为 “European Conformity” 即”欧洲共同体”, 事实上,CE还是欧共体许多国家语种中的"欧共体"这一词组的缩写,原来用英语词组EUROPEAN COMMUNITY 缩写为EC,后因欧共体在法文…

python---字典(1)

字典的创建 字典: 是一种存储键值对的 键值对: 键(key) 值(value) 根据key可以快速的找到value (key和value有一定的映射关系) 在python字典中可以包含很多键值对,但是键是唯一的. 创建一个空的字典 创建字典的同时,设置初始值 推荐写法是如下的字典的初始化: 字典查找ke…

unittest教程__assert断言(4)

测试用例是否测试通过是通过将预期结果与实际结果做比较来判定的,那代码中怎么来判定用例是否通过呢?在python中这种判定的方法就叫做断言,断言可以使用python的assert方法,也可以使用unittest框架提供的一系列断言方法。 unitte…

强化历程2-Vue+axios+ajax面试系列(2023.6.17)

因为主要是后端,在此训练都是非常基础的题目,后续会持续更新… 文章目录 强化历程2-Vueaxiosajax面试系列(2023.6.18第一次更新)题目汇总1 Vue常用指令2 v-show和v-if区别3 讲一讲MVVM4 vue特点?5 vue组件之间的传值6 vue整合其他框架7 vue生命周期8 vue中实现路由…

通过共享内存进行通信(嵌入式学习)

通过共享内存进行通信 概念特点函数示例代码 概念 在Linux中,共享内存是一种进程间通信(IPC)机制,允许多个进程共享同一块内存区域。这种通信方式可以提供高效的数据传输,特别适用于需要频繁交换数据的场景。 IO间进…

【运动控制】安装固高运动控制卡驱动程序

【运动控制】安装固高运动控制卡驱动程序 1、背景2、卸载PCI设备3、安装驱动4、安装验证 1、背景 运动控制卡是用来做什么的?顾名思义,用来控制电机转动的。 本博客简单介绍固高科技(深圳)有限公司的运动控制卡的驱动安装。 在购买了固高控制卡后&…

网络层(3)6/12

1.网络层 网络层最大的特点就是提供路由,路由就是分组从源到目的地址时,绝定的端到端的路径 路由:路由是网络层最主要的工作任务 网关:一个网络域到另一个网络域的关卡,主要用于不同网段之间的通讯 路由的获取方式&…