es 聚合操作(一)

news2024/11/18 20:02:20

前言

Elasticsearch除搜索以外,提供了针对ES 数据进行统计分析的功能。聚合(aggregations)可以让我们极其方便的实现对数据的统计、分析、运算。例如:

  • 衣服品牌的受欢迎程度
  • 这些衣服的平均价格、最高价格、最低价格
  • 这些衣服的每天、每月销量如何

使用场景

聚合查询可以用于各种场景,比如商业智能、数据挖掘、日志分析等等。

  • 电商平台的销售分析:统计每个地区的销售额、每个用户的消费总额、每个产品的销售量等,以便更好地了解销售情况和趋势。
  • 社交媒体的用户行为分析:统计每个用户的发布次数、转发次数、评论次数等,以便更好地了解用户行为和趋势,同时可以将数据按照地区、时间、话题等维度进行分析。
  • 物流企业的运输分析:统计每个区域的运输量、每个车辆的运输次数、每个司机的行驶里程等,以便更好地了解运输情况和优化运输效率。
  • 金融企业的交易分析:统计每个客户的交易总额、每个产品的销售量、每个交易员的业绩等,以便更好地了解交易情况和优化业务流程。
  • 智能家居的设备监控分析:统计每个设备的使用次数、每个家庭的能源消耗量、每个时间段的设备使用率等,以便更好地了解用户需求和优化设备效能。

基本语法

聚合查询的语法结构与其他查询相似,通常包含以下部分:

  • 查询条件:指定需要聚合的文档,可以使用标准的 Elasticsearch 查询语法,如 term、match、range 等等。
  • 聚合函数:指定要执行的聚合操作,如 sum、avg、min、max、terms、date_histogram 等等。每个聚合命令都会生成一个聚合结果。
  • 聚合嵌套:聚合命令可以嵌套,以便更细粒度地分析数据。
GET <index_name>/_search
{
  "aggs": {
    "<aggs_name>": { // 聚合名称需要自己定义
      "<agg_type>": {
        "field": "<field_name>"
      }
    }
  }
}
  • aggs_name:聚合函数的名称,需要自己定义
  • agg_type:聚合种类,比如是桶聚合(terms)或者是指标聚合(avg、sum、min、max等)
  • field_name:字段名称或者叫域名。

示例数据

#创建索引库
PUT /employees
{
  "mappings": {
    "properties": {
      "age":{
        "type": "integer"
      },
      "gender":{
        "type": "keyword"
      },
      "job":{
         "type" : "text",
          "fields" : {
            "keyword" : {
              "type" : "keyword",
              "ignore_above" : 50
            }
          }
      },
      "name":{
        "type": "keyword"
      },
      "salary":{
        "type": "integer"
      }
    }
  }
}

PUT /employees/_bulk
{ "index" : {  "_id" : "1" } }
{ "name" : "Emma","age":32,"job":"Product Manager","gender":"female","salary":35000 }
{ "index" : {  "_id" : "2" } }
{ "name" : "Underwood","age":41,"job":"Dev Manager","gender":"male","salary": 50000}
{ "index" : {  "_id" : "3" } }
{ "name" : "Tran","age":25,"job":"Web Designer","gender":"male","salary":18000 }
{ "index" : {  "_id" : "4" } }
{ "name" : "Rivera","age":26,"job":"Web Designer","gender":"female","salary": 22000}
{ "index" : {  "_id" : "5" } }
{ "name" : "Rose","age":25,"job":"QA","gender":"female","salary":18000 }
{ "index" : {  "_id" : "6" } }
{ "name" : "Lucy","age":31,"job":"QA","gender":"female","salary": 25000}
{ "index" : {  "_id" : "7" } }
{ "name" : "Byrd","age":27,"job":"QA","gender":"male","salary":20000 }
{ "index" : {  "_id" : "8" } }
{ "name" : "Foster","age":27,"job":"Java Programmer","gender":"male","salary": 20000}
{ "index" : {  "_id" : "9" } }
{ "name" : "Gregory","age":32,"job":"Java Programmer","gender":"male","salary":22000 }
{ "index" : {  "_id" : "10" } }
{ "name" : "Bryant","age":20,"job":"Java Programmer","gender":"male","salary": 9000}
{ "index" : {  "_id" : "11" } }
{ "name" : "Jenny","age":36,"job":"Java Programmer","gender":"female","salary":38000 }
{ "index" : {  "_id" : "12" } }
{ "name" : "Mcdonald","age":31,"job":"Java Programmer","gender":"male","salary": 32000}
{ "index" : {  "_id" : "13" } }
{ "name" : "Jonthna","age":30,"job":"Java Programmer","gender":"female","salary":30000 }
{ "index" : {  "_id" : "14" } }
{ "name" : "Marshall","age":32,"job":"Javascript Programmer","gender":"male","salary": 25000}
{ "index" : {  "_id" : "15" } }
{ "name" : "King","age":33,"job":"Java Programmer","gender":"male","salary":28000 }
{ "index" : {  "_id" : "16" } }
{ "name" : "Mccarthy","age":21,"job":"Javascript Programmer","gender":"male","salary": 16000}
{ "index" : {  "_id" : "17" } }
{ "name" : "Goodwin","age":25,"job":"Javascript Programmer","gender":"male","salary": 16000}
{ "index" : {  "_id" : "18" } }
{ "name" : "Catherine","age":29,"job":"Javascript Programmer","gender":"female","salary": 20000}
{ "index" : {  "_id" : "19" } }
{ "name" : "Boone","age":30,"job":"DBA","gender":"male","salary": 30000}
{ "index" : {  "_id" : "20" } }
{ "name" : "Kathy","age":29,"job":"DBA","gender":"female","salary": 20000}

Metric Aggregation

—些数学运算,可以对文档字段进行统计分析,类比Mysql中的 min(), max(), sum() 操作。

  • 单值分析︰只输出一个分析结果
    • min, max, avg, sum
    • Cardinality(类似distinct Count)
  • 多值分析:输出多个分析结果
  • stats(统计), extended stats
  • percentile (百分位), percentile rank
  • top hits(排在前面的示例)

查询员工的最低、最高和平均工资

POST /employees/_search
{
  "aggs": {
    "max_salary": {
      "max": {
        "field": "salary"
      }
    },
    "min_salary": {
      "min": {
        "field": "salary"
      }
    },
    "avg_salary": {
      "avg": {
        "field": "salary"
      }
    }
  }
}

注意查询的时候如果不加 size = 0 会查询出来默认的 10 条数据

如果不想要数据只想要统计结果,可以加上 size = 0

POST /employees/_search
{
  "size": 0, 
  "aggs": {
    "max_salary": {
      "max": {
        "field": "salary"
      }
    },
    "min_salary": {
      "min": {
        "field": "salary"
      }
    },
    "avg_salary": {
      "avg": {
        "field": "salary"
      }
    }
  }
}

stats 可以输出多个统计值

POST /employees/_search
{ "size": 0, 
  "aggs": {
    "stats_salary": {
      "stats": {
        "field": "salary"
      }
    }
  }
}

cardinate 对搜索结果去重

POST /employees/_search
{
  "size": 0, 
  "aggs": {
    "cardinate": {
      "cardinality": {
        "field": "job"
      }
    }
  }
}

这里需要注意:如果需要计算的字段是 text 类型,会报错

解决方案有两种:

方案一、开启 fielddata :

然后就可以对 job 进行聚合计算了

但需要注意的是:

  1. 内存使用:为大量或高基数的 text 字段启用 fielddata 可能会导致大量的内存使用,这可能会影响到集群的性能和稳定性。
  2. 性能:加载大量的 fielddata 可能会降低查询性能。
  3. 统计值:会对 job 进行分词 然后对分词进行 terms


可以看到上面示例,分类的指标都是分词后的结果

下面的示例也是一样的,统计的值也是分词后的结果

这里可以看到 分词后分类有 10 条数,但是使用 keyword 只有 7 条数据

原因就是,fielddata 对先分词 再对分词进行分类计算

PUT /employees/_mapping
{
  "properties" : {
    "job":{
       "type":  "text",
       "fielddata": true
    }
  }
}

# 对 Text 字段进行分词,分词后的terms
POST /employees/_search
{
  "size": 0,
  "aggs": {
    "jobs": {
      "terms": {
        "field":"job"
      }
    }
  }
}

方案二、keyword类型

如果你的目的是对某个字段进行排序或聚合,但不需要全文搜索,那么考虑使用 keyword 类型而不是 text 类型可能是一个更好的选择。keyword 类型默认启用 fielddata,并更适合此类操作。

上面这个示例 keyword 不会对字段的值进行分词,统计值 7 条数据

POST /employees/_search
{
  "size": 0,
  "aggs": {
    "cardinate": {
      "cardinality": {
        "field": "job.keyword"
      }
    }
  }
}

Bucket Aggregation

按照一定的规则,将文档分配到不同的桶中,从而达到分类的目的。ES提供的一些常见的 Bucket Aggregation。

  • Terms,需要字段支持filedata
    • keyword 默认支持fielddata
    • text需要在Mapping 中开启fielddata,会按照分词后的结果进行分桶
  • 数字类型
    • Range / Data Range
    • Histogram(直方图) / Date Histogram
  • 支持嵌套: 也就在桶里再做分桶

桶聚合可以用于各种场景,例如:

  • 对数据进行分组统计,比如按照地区、年龄段、性别等字段进行分组统计。
  • 对时间序列数据进行时间段分析,比如按照每小时、每天、每月、每季度、每年等时间段进行分析。
  • 对各种标签信息分类,并统计其数量。

获取job的分类信息

GET /employees/_search
{
  "size": 0, 
  "aggs": {
    "jobs": {
      "terms": {
        "field": "job.keyword"
      }
    }
  }
}

聚合可配置属性有:

  • field:指定聚合字段
  • size:指定聚合结果数量
  • order:指定聚合结果排序方式

默认情况下,Bucket聚合会统计Bucket内的文档数量,记为_count,并且按照_count降序排序。我们可以指定order属性,自定义聚合的排序方式:

GET /employees/_search
{
  "size": 0, 
  "aggs": {
    "jobs": {
      "terms": {
        "field": "job.keyword",
        "size": 10,
        "order": {
          "_count": "asc"
        }
      }
    }
  }
}

只对 salary 20000 以上的进行聚合

#限制聚合范围
POST /employees/_search
{
  "query": {
    "range": {
      "salary": {
        "gte": 20000
      }
    }
  },
  "size": 0, 
  "aggs": {
    "jobs": {
      "terms": {
        "field": "job.keyword",
        "size": 10,
        "order": {
          "_count": "asc"
        }
      }
    }
  }
}

自定义范围对 salary 分桶

#Salary Range分桶,可以自己定义 key
POST employees/_search
{
  "size": 0,
  "aggs": {
    "salary_range": {
      "range": {
        "field":"salary",
        "ranges":[
          {
            "to":10000
          },
          {
            "from":10000,
            "to":20000
          },
          {
            "key":">20000",
            "from":20000
          }
        ]
      }
    }
  }
}

以 salary 5000 为间隔进行分桶

POST /employees/_search
{
  "size": 0, 
  "aggs": {
    "salary_histrogram": {
      "histogram": {
        "field": "salary",
        "interval": 5000
      }
    }
  }
}

也可以指定范围:

POST /employees/_search
{
  "size": 0, 
  "aggs": {
    "salary_histrogram": {
      "histogram": {
        "field": "salary",
        "interval": 5000,
        "extended_bounds": {
          "min": 0,
          "max": 60000
        }
      }
    }
  }
}

但是这种方式指定范围,好像默认也会输出到最大的那个桶,

我这里指定最大是 10000 但是也会把索引中最大的值输出,

既然默认都会输出最大值,那么指定超过最大值的数值,后面都是 0 也没有统计的必要了

这里感兴趣的小伙伴可以研究一下~

然后如果需要对指定范围的薪资进行统计,可以使用 range query

这样就只统计 20000 以内的数据了

POST /employees/_search
{
  "query": {
    "range": {
      "salary": {
        "gte": 0,
        "lte": 20000
      }
    }
  }, 
  "size": 0
  , "aggs": {
    "salary_histrogram": {
      "histogram": {
        "field": "salary",
        "interval": 5000
      }
    }
  }
}

top_hits

应用场景: 当获取分桶后,桶内最匹配的顶部文档列表

比如:不同工种中,年纪最大的3个员工的具体信息

POST /employees/_search
{
  "size": 0,
  "aggs": {
    "jobs": {
      "terms": {
        "field":"job.keyword"
      },
      "aggs":{
        "old_employee":{
          "top_hits":{
            "size":3,
            "sort":[
              {
                "age":{
                  "order":"desc"
                }
              }
            ]
          }
        }
      }
    }
  }
}

嵌套聚合

按照工作类型分桶,并统计工资信息

# 嵌套聚合1,按照工作类型分桶,并统计工资信息
POST employees/_search
{
  "size": 0,
  "aggs": {
    "Job_salary_stats": {
      "terms": {
        "field": "job.keyword"
      },
      "aggs": {
        "salary": {
          "stats": {
            "field": "salary"
          }
        }
      }
    }
  }
}

根据工作类型分桶,然后按照性别分桶,计算工资的统计信息

# 多次嵌套。根据工作类型分桶,然后按照性别分桶,计算工资的统计信息
POST employees/_search
{
  "size": 0,
  "aggs": {
    "Job_gender_stats": {
      "terms": {
        "field": "job.keyword"
      },
      "aggs": {
        "gender_stats": {
          "terms": {
            "field": "gender"
          },
          "aggs": {
            "salary_stats": {
              "stats": {
                "field": "salary"
              }
            }
          }
        }
      }
    }
  }
}

感谢观看!!!感兴趣的小伙伴可以关注收藏,持续更新中~~~

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

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

相关文章

cpp qt 一个奇怪的bug

今天在用cpp qt的时候发现了一个奇怪的东西 这是我的源代码 #include "mywidget.h" #include <QPushButton>myWidget::myWidget(QWidget *parent): QWidget(parent) {QPushButton * btn1 new QPushButton;btn1->show();btn1->setParent(this);btn1-&g…

在集群模式下,Redis 的 key 是如何寻址的?分布式寻址都有哪些算法?了解一致性 hash 算法吗?

目录 一、分布式寻址算法 1. hash 算法 2. 一致性 hash 算法 3. Redis cluster 的 hash slot 算法 二、Redis cluster 的高可用与主备切换原理 1. 判断节点宕机 2. 从节点过滤 3. 从节点选举 4. 与哨兵比较 一、分布式寻址算法 hash 算法(大量缓存重建) 一致性 hash…

【代码随想录 | 链表 02】反转链表

文章目录 2.反转链表2.1题目2.2解法2.2.1双指针法2.2.2递归法 2.反转链表 2.1题目 206.反转链表——力扣链接 给你单链表的头节点 head &#xff0c;请你反转链表&#xff0c;并返回反转后的链表。 示例一&#xff1a; 输入&#xff1a;head [1,2,3,4,5] 输出&#xff1a;…

重建大师出现图中密集匹配失败的情况,是什么原因导致的?

可以检查瓦块是否位于测区边缘&#xff0c;边缘瓦块可以忽略&#xff1b;如果是中间区域的话&#xff0c;可能中间文件有异常&#xff0c;可以新建个reconstruction&#xff0c;然后单独提交失败的瓦块。 重建大师是一款专为超大规模实景三维数据生产而设计的集群并行处理软件&…

数据结构:7、队列

一、队列的概念与结构 队列&#xff1a;只允许在一端进行插入数据操作&#xff0c;在另一端进行删除数据操作的特殊线性表&#xff0c;队列具有先进先出FIFO(First In First Out) 入队列&#xff1a;进行插入操作的一端称为队尾 出队列&#xff1a;进行删除操作的一端称为队头…

Cisco Packet Tracer模拟器实现路由器的路由配置及网络的安全配置

1. 内容 1. 配置路由器实现多个不同网络间的通信&#xff0c;路由器提供的路由协议包括静态路由协议、RIP动态路由、OSPF动态路由协议等等&#xff0c;训练内容包括路由器的静态路由配置、路由器的RIP动态路由配置、路由器的OSPF动态路由配置以及路由器的路由重分布配置。 2.…

Css基础——溢出文字省略号表达

1. 单行文本溢出显示省略号&#xff1a; 1.1、方法&#xff1a; 1. 先强制一行内显示文本*/ white-space: nowrap; &#xff08; 默认 normal 自动换行&#xff09; 2. 超出的部分隐藏*/ overflow: hidden; 3. 文字用省略号替代超出的部分*/ text-overflow: ellipsis; 1.2、代…

实战 | 基于YOLOv9和OpenCV实现车辆跟踪计数(步骤 + 源码)

导 读 本文主要介绍使用YOLOv9和OpenCV实现车辆跟踪计数&#xff08;步骤 源码&#xff09;。 实现步骤 监控摄像头可以有效地用于各种场景下的车辆计数和交通流量统计。先进的计算机视觉技术&#xff08;例如对象检测和跟踪&#xff09;可应用于监控录像&#xff0c;…

单调队列 维护区间最值(板子+两道练手)

1.P1886 滑动窗口 /【模板】单调队列https://www.luogu.com.cn/problem/P1886 板子题&#xff0c;传送门在上方 // Problem: // P1886 滑动窗口 /【模板】单调队列 // // Contest: Luogu // URL: https://www.luogu.com.cn/problem/P1886 // Memory Limit: 500 MB //…

Zookeeper3.5.9源码编译和启动

目录 参考链接1. 下载源码2. 准备更高版本的JDK和Maven环境Java 8Maven 3.6.3 3. 用IDEA打开项目进行编译和启动3.1. 设置maven版本3.2. 设置JDK版本为1.83.3. 切换 Maven profiles 选项到 java-build3.4. 执行 Ant build 生成和编译Java文件3.4.1. 执行ant build-generated而非…

微信小程序之vue按钮切换内容变化

效果图如下&#xff1b; 上代码 <template><view class"content"><view class"searchDiv"><view class"paytab"><view class"buttab" v-for"(t,index) in tabList" :key"index" clic…

叶子分享站PHP源码

叶子网盘分享站PHP网站源码&#xff0c;创建无限级文件夹&#xff0c;上传文件&#xff0c;可进行删除&#xff0c;下载等能很好的兼容服务器。方便管理者操作&#xff0c;查看更多的下载资源以及文章&#xff0c;新增分享功能&#xff0c;异步上传文件/资源等 PHP网盘源码优势…

Docker进阶:容器与镜像的导入和导出

Docker进阶&#xff1a;容器与镜像的导入和导出 1、容器&#xff08;Container&#xff09;和镜像&#xff08;Image&#xff09;的区别2、导出 Docker 容器3、导入 Docker 容器快照为镜像4、导出 Docker 镜像5、导入 Docker 镜像6、docker export 和 docker save区别7、docker…

优先级队列 priority_queue 的使用及示例代码

一、简介 priority_queue 即 优先级队列&#xff08;一种特殊的队列&#xff0c;其中的元素按照一定的优先级顺序排列&#xff0c;每次取出时都会取出具有最高优先级的元素&#xff0c;或者说可以获取队列中的最大/最小元素&#xff09;&#xff0c;它是C标准模板库&#xff0…

构建部署_Jenkins介绍与安装

构建部署_Jenkins介绍与安装 构建部署_Jenkins介绍与安装Jenkins介绍Jenkins安装 构建部署_Jenkins介绍与安装 Jenkins介绍 Jenkins是一个可扩展的持续集成引擎。 持续集成&#xff0c;就是通常所说的CI&#xff08;Continues Integration&#xff09;&#xff0c;可以说是现…

Android的UI渲染机制(二)

安卓系统中有 2 种 vsync 信号&#xff1a; &#xff08;1&#xff09;屏幕产生的硬件 vsync信号&#xff0c;主要用于通知应用程序开始在自己的窗口“画布”中执行一帧画面的绘制和渲染 &#xff08;2&#xff09;由SurfaceFlinger将其转成的软件 vsync 信号&#xff0c;经由…

十六、接口隔离原则、反射、依赖注入

接口隔离原则、反射、特性、依赖注入 接口隔离原则 客户端不应该依赖它不需要的接口&#xff1b;一个类对另一个类的依赖应该建立在最小的接口上。 五种原则当中的i 上一章中的接口&#xff0c;即契约。 契约就是在说两件事&#xff0c;甲方说自己不会多要&#xff0c;乙方会在…

(黑马出品_高级篇_03)SpringCloud+RabbitMQ+Docker+Redis+搜索+分布式

&#xff08;黑马出品_高级篇_03&#xff09;SpringCloudRabbitMQDockerRedis搜索分布式 微服务技术——多级缓存 今日目标1.什么是多级缓存2.JVM进程缓存2.1.导入案例2.1.1.安装MySQL2.1.1.1.准备目录2.1.1.2.运行命令2.1.1.3.修改配置 2.1.1.4.…

优雅的记录日志,拒绝打印模糊信息导致bug定位难

想必大家都有过这样的经历&#xff1a;在项目中遇到报错需要紧急修复时&#xff0c;却因为日志信息模糊不清&#xff0c;无法迅速准确地定位到错误源头&#xff0c;这确实让人感到十分苦恼和无奈。 在新入职一家公司并着手修改遗留bug时&#xff0c;经常发现之前的开发者并未记…

用云服务器构建gpt和stable-diffusion大模型

用云服务器构建gpt和stable-diffusion大模型 一、前置知识二、用云端属于自己的聊天chatGLM3step1、项目配置step2、环境配置1、前置知识2、环境配置流程 step3、创建镜像1、前置知识2、创建镜像流程 step4、通过 Gradio 创建ChatGLM交互界面1、前置知识2、创建ChatGLM交互界面…