ElasticSearch - Bucket Selector使用指南

news2024/11/5 17:20:47

文章目录

  • 官方文档
  • Bucket Selector
    • 1. 定义
    • 2. 工作原理
    • 3. 使用场景与示例
      • 使用场景
        • 官方案例
        • 示例2
    • 4. 注意事项
    • 5. 总结

在这里插入图片描述


官方文档

https://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations.html

在这里插入图片描述

在这里插入图片描述


Bucket Selector

https://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-pipeline-bucket-selector-aggregation.html

在这里插入图片描述在这里插入图片描述
在这里插入图片描述


1. 定义

bucket_selector 是 ElasticSearch 中的一种聚合管道(Pipeline Aggregation),用于对已生成的聚合桶(bucket)进行后处理。它允许根据聚合结果动态过滤和选择桶,从而帮助用户更精确地控制查询结果。

2. 工作原理

  • 输入bucket_selector 接受一个或多个聚合桶作为输入。
  • 脚本:通过脚本计算每个桶的条件,例如根据聚合值判断是否保留该桶。
  • 输出:返回符合条件的桶,其余的桶将被过滤掉。
  1. buckets_path:用于指定脚本中的变量和对应的聚合路径。例如,可以定义一个路径映射,将某个子聚合的结果(如总和或计数)传递给变量。
  2. script:通过脚本来判断某个桶是否保留。脚本语言通常为Painless,脚本必须返回一个布尔值,true表示保留该桶,false表示过滤掉

3. 使用场景与示例

使用场景

  • 当需要根据聚合的统计数据来决定显示哪些结果时。
  • 可以在进行多层聚合时,优化最终返回的桶。

官方案例

以下是一个实际应用:假设想筛选出每月销售额超过200的结果。可以使用如下DSL查询:


PUT /sales
{
  "mappings": {
    "properties": {
      "date": {
        "type": "date"
      },
      "price": {
        "type": "double"
      }
    }
  }
}


POST /sales/_bulk
{ "index": { "_id": "1" } }
{ "date": "2023-01-01", "price": 100.0 }
{ "index": { "_id": "2" } }
{ "date": "2023-01-15", "price": 150.0 }
{ "index": { "_id": "3" } }
{ "date": "2023-02-01", "price": 300.0 }
{ "index": { "_id": "4" } }
{ "date": "2023-02-10", "price": 50.0 }
{ "index": { "_id": "5" } }
{ "date": "2023-03-01", "price": 400.0 }
{ "index": { "_id": "6" } }
{ "date": "2023-03-15", "price": 250.0 }
{ "index": { "_id": "7" } }
{ "date": "2023-04-01", "price": 350.0 }
{ "index": { "_id": "8" } }
{ "date": "2023-04-10", "price": 200.0 }
{ "index": { "_id": "9" } }
{ "date": "2023-05-01", "price": 500.0 }
{ "index": { "_id": "10" } }
{ "date": "2023-05-15", "price": 300.0 }




POST /sales/_search
{
  "size": 0,
  "aggs": {
    "sales_per_month": {
      "date_histogram": {
        "field": "date",
        "calendar_interval": "month"
      },
      "aggs": {
        "total_sales": {
          "sum": {
            "field": "price"
          }
        },
        "sales_bucket_filter": {
          "bucket_selector": {
            "buckets_path": {
              "totalSales": "total_sales"
            },
            "script": "params.totalSales > 600"
          }
        }
      }
    }
  }
}

这个DSL是一个用于Elasticsearch的聚合查询,目的是统计每个月的销售总额,并筛选出销售总额超过600的月份。下

  1. size: 0
  • 作用:表示在查询结果中不返回文档本身,只返回聚合结果。这通常用于只关心聚合结果而不需要实际数据时。
  1. aggs
  • 作用:定义聚合操作的容器。这里的聚合是为了对销售数据进行统计。
  1. sales_per_month
  • 类型date_histogram
    • 功能:将数据按照时间段(这里是月份)进行分组。
    • 参数
      • field: 指定用于分组的日期字段,这里是 date
      • calendar_interval: 设置时间间隔,这里是按月进行分组。
  1. total_sales
  • 类型sum
    • 功能:对每个月的销售额进行求和。
    • 参数
      • field: 指定需要求和的字段,这里是 price。每个月的销售总额将被计算并存储在这个聚合中。
  1. sales_bucket_filter
  • 类型bucket_selector
    • 功能:用于根据特定条件过滤桶(即月份)。
    • 参数
      • buckets_path: 定义如何访问其他聚合的结果,这里指定了 totalSales 对应于 total_sales 聚合。
      • script: 使用Painless脚本来判断是否保留桶。这里的条件是 params.totalSales > 600,这意味着只有当某个月的总销售额超过600时,该月份的桶才会被保留。

总结

这个DSL的整体作用是:

  • 按月份对销售数据进行分组。
  • 计算每个月的销售总额。
  • 只保留销售总额超过600的月份结果。

最终,这将返回一个包含销售额超过600的月份的聚合结果,方便进行数据分析。
在这里插入图片描述


示例2

假设有一个日志索引,包含用户活动的文档,我们想要按用户分组并计算每个用户的活动次数,但只希望返回活动次数超过10的用户。

 
PUT /user_activity
{
  "mappings": {
    "properties": {
      "user_id": {
        "type": "keyword"
      },
      "activity": {
        "type": "keyword"
      },
      "timestamp": {
        "type": "date"
      }
    }
  }
}



POST /user_activity/_bulk
{ "index": { "_id": "1" } }
{ "user_id": "user1", "activity": "login", "timestamp": "2024-10-01T10:00:00Z" }
{ "index": { "_id": "2" } }
{ "user_id": "user1", "activity": "view_page", "timestamp": "2024-10-01T10:05:00Z" }
{ "index": { "_id": "3" } }
{ "user_id": "user1", "activity": "logout", "timestamp": "2024-10-01T10:10:00Z" }
{ "index": { "_id": "4" } }
{ "user_id": "user1", "activity": "login", "timestamp": "2024-10-01T11:00:00Z" }
{ "index": { "_id": "5" } }
{ "user_id": "user1", "activity": "view_page", "timestamp": "2024-10-01T11:05:00Z" }
{ "index": { "_id": "6" } }
{ "user_id": "user1", "activity": "logout", "timestamp": "2024-10-01T11:10:00Z" }
{ "index": { "_id": "7" } }
{ "user_id": "user2", "activity": "login", "timestamp": "2024-10-01T12:00:00Z" }
{ "index": { "_id": "8" } }
{ "user_id": "user2", "activity": "upload_file", "timestamp": "2024-10-01T12:15:00Z" }
{ "index": { "_id": "9" } }
{ "user_id": "user3", "activity": "logout", "timestamp": "2024-10-01T12:30:00Z" }
{ "index": { "_id": "10" } }
{ "user_id": "user4", "activity": "login", "timestamp": "2024-10-01T13:00:00Z" }
{ "index": { "_id": "11" } }
{ "user_id": "user4", "activity": "logout", "timestamp": "2024-10-01T13:05:00Z" }
{ "index": { "_id": "12" } }
{ "user_id": "user5", "activity": "login", "timestamp": "2024-10-01T14:00:00Z" }
{ "index": { "_id": "13" } }
{ "user_id": "user5", "activity": "view_page", "timestamp": "2024-10-01T14:10:00Z" }
{ "index": { "_id": "14" } }
{ "user_id": "user5", "activity": "logout", "timestamp": "2024-10-01T14:15:00Z" }
{ "index": { "_id": "15" } }
{ "user_id": "user6", "activity": "login", "timestamp": "2024-10-01T15:00:00Z" }
{ "index": { "_id": "16" } }
{ "user_id": "user6", "activity": "view_page", "timestamp": "2024-10-01T15:05:00Z" }
{ "index": { "_id": "17" } }
{ "user_id": "user6", "activity": "logout", "timestamp": "2024-10-01T15:10:00Z" }
{ "index": { "_id": "18" } }
{ "user_id": "user7", "activity": "login", "timestamp": "2024-10-01T16:00:00Z" }
{ "index": { "_id": "19" } }
{ "user_id": "user7", "activity": "upload_file", "timestamp": "2024-10-01T16:05:00Z" }
{ "index": { "_id": "20" } }
{ "user_id": "user7", "activity": "logout", "timestamp": "2024-10-01T16:10:00Z" }
{ "index": { "_id": "21" } }
{ "user_id": "user8", "activity": "login", "timestamp": "2024-10-01T17:00:00Z" }
{ "index": { "_id": "22" } }
{ "user_id": "user8", "activity": "view_page", "timestamp": "2024-10-01T17:05:00Z" }
{ "index": { "_id": "23" } }
{ "user_id": "user8", "activity": "logout", "timestamp": "2024-10-01T17:10:00Z" }
{ "index": { "_id": "24" } }
{ "user_id": "user9", "activity": "login", "timestamp": "2024-10-01T18:00:00Z" }
{ "index": { "_id": "25" } }
{ "user_id": "user9", "activity": "view_page", "timestamp": "2024-10-01T18:05:00Z" }
{ "index": { "_id": "26" } }
{ "user_id": "user9", "activity": "logout", "timestamp": "2024-10-01T18:10:00Z" }
{ "index": { "_id": "27" } }
{ "user_id": "user10", "activity": "login", "timestamp": "2024-10-01T19:00:00Z" }
{ "index": { "_id": "28" } }
{ "user_id": "user10", "activity": "view_page", "timestamp": "2024-10-01T19:05:00Z" }
{ "index": { "_id": "29" } }
{ "user_id": "user10", "activity": "logout", "timestamp": "2024-10-01T19:10:00Z" }
{ "index": { "_id": "30" } }
{ "user_id": "user11", "activity": "login", "timestamp": "2024-10-01T20:00:00Z" }
{ "index": { "_id": "31" } }
{ "user_id": "user11", "activity": "view_page", "timestamp": "2024-10-01T20:05:00Z" }
{ "index": { "_id": "32" } }
{ "user_id": "user11", "activity": "logout", "timestamp": "2024-10-01T20:10:00Z" }
{ "index": { "_id": "33" } }
{ "user_id": "user12", "activity": "login", "timestamp": "2024-10-01T21:00:00Z" }
{ "index": { "_id": "34" } }
{ "user_id": "user12", "activity": "upload_file", "timestamp": "2024-10-01T21:05:00Z" }
{ "index": { "_id": "35" } }
{ "user_id": "user12", "activity": "logout", "timestamp": "2024-10-01T21:10:00Z" }
{ "index": { "_id": "36" } }
{ "user_id": "user13", "activity": "login", "timestamp": "2024-10-01T22:00:00Z" }
{ "index": { "_id": "37" } }
{ "user_id": "user13", "activity": "view_page", "timestamp": "2024-10-01T22:05:00Z" }
{ "index": { "_id": "38" } }
{ "user_id": "user13", "activity": "logout", "timestamp": "2024-10-01T22:10:00Z" }
{ "index": { "_id": "39" } }
{ "user_id": "user14", "activity": "login", "timestamp": "2024-10-01T23:00:00Z" }
{ "index": { "_id": "40" } }
{ "user_id": "user14", "activity": "view_page", "timestamp": "2024-10-01T23:05:00Z" }
{ "index": { "_id": "41" } }
{ "user_id": "user14", "activity": "logout", "timestamp": "2024-10-01T23:10:00Z" }
{ "index": { "_id": "42" } }
{ "user_id": "user15", "activity": "login", "timestamp": "2024-10-02T00:00:00Z" }
{ "index": { "_id": "43" } }
{ "user_id": "user15", "activity": "upload_file", "timestamp": "2024-10-02T00:05:00Z" }
{ "index": { "_id": "44" } }
{ "user_id": "user15", "activity": "logout", "timestamp": "2024-10-02T00:10:00Z" }
{ "index": { "_id": "45" } }
{ "user_id": "user16", "activity": "login", "timestamp": "2024-10-02T01:00:00Z" }
{ "index": { "_id": "46" } }
{ "user_id": "user16", "activity": "view_page", "timestamp": "2024-10-02T01:05:00Z" }
{ "index": { "_id": "47" } }
{ "user_id": "user16", "activity": "logout", "timestamp": "2024-10-02T01:10:00Z" }
{ "index": { "_id": "48" } }
{ "user_id": "user17", "activity": "login", "timestamp": "2024-10-02T02:00:00Z" }
{ "index": { "_id": "49" } }
{ "user_id": "user17", "activity": "upload_file", "timestamp": "2024-10-02T02:05:00Z" }
{ "index": { "_id": "50" } }
{ "user_id": "user17", "activity": "logout", "timestamp": "2024-10-02T02:10:00Z" }




POST /user_activity/_search
{
  "size": 0,
  "aggs": {
    "users": {
      "terms": {
        "field": "user_id"
      },
      "aggs": {
        "activity_count": {
          "value_count": {
            "field": "activity"
          }
        },
        "filtered_users": {
          "bucket_selector": {
            "buckets_path": {
              "count": "activity_count"
            },
            "script": "params.count > 5"
          }
        }
      }
    }
  }
}


  1. 总体结构
  • 请求类型POST /user_activity/_search 这表示我们正在对 user_activity 索引执行搜索请求。
  • size:设置为 0,表示不返回文档,仅返回聚合结果。
  1. 聚合部分 (aggs)
  • users:这是一个聚合的名称,用于聚合结果的分组。
    • terms:这是一个聚合类型,表示我们希望按 user_id 字段对文档进行分组。每个不同的 user_id 将生成一个桶。
  1. 嵌套聚合
  • activity_count

    • value_count:这是另一个聚合,计算每个用户桶中 activity 字段的文档数量。换句话说,它统计每个用户的活动次数。
  • filtered_users

    • bucket_selector:这是一个聚合管道,允许对已生成的桶进行后处理。
    • buckets_path:这是一个路径定义,指定了输入到 bucket_selector 的聚合结果。在这里,count 被定义为指向 activity_count 聚合的结果。
    • script:这是一个条件语句,用于筛选桶。在这里,脚本判断活动次数是否大于5。只有符合这个条件的用户桶才会被保留。

总结

该DSL的主要功能是:

  1. user_id 聚合用户活动数据。
  2. 计算每个用户的活动数量。
  3. 仅筛选出活动次数大于5的用户。
    在这里插入图片描述

4. 注意事项

  • 由于bucket_selector是在所有聚合完成后执行的,它不能减少执行时间。
  • 在一些复杂场景中(如使用cardinality聚合),需要确保将bucket_selector放置在正确的父级聚合中,否则会出现不兼容的错误

5. 总结

bucket_selector 是 ElasticSearch 中用于后处理聚合桶的强大工具,可以根据聚合计算的结果动态地筛选出感兴趣的桶。它在数据分析和可视化中非常有用,可以帮助用户精准控制查询结果。

在这里插入图片描述

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

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

相关文章

“死鱼眼”,不存在的,一个提词小技巧,拯救的眼神——将内容说给用户,而非读给用户!

视频录制时,死鱼眼问题常见 即便内容再好,眼神死板也会减分 痛点真痛:拍视频时容易紧张 面对镜头,许多人难免紧张 神情僵硬,眼神无光,甚至忘词 这不仅影响表现,还让人难以专注 忘我场景&#x…

PyQt5实战——多脚本集合包,UI以及工程布局(二)

个人博客:苏三有春的博客 系列往期: PyQt5实战——多脚本集合包,前言与环境配置(一) 布局 2.1 UI页面布局 整体框架分为分为三个部分,垂直分布。 第一个部分为功能选择按钮(如UTF-8转换&#…

《Python网络安全项目实战》项目2 Python基础练习_总复习(1)

《Python网络安全项目实战》项目2 Python基础练习 总复习(1) 班级: 姓名: 实训成绩: 任务单成绩 : 输入用户名密码并将其输出打印。 userName _____________________ passWord ______________________ #输…

数组排序简介-基数排序(Radix Sort)

基本思想 将整数按位数切割成不同的数字,然后从低位开始,依次到高位,逐位进行排序,从而达到排序的目的。 算法步骤 基数排序算法可以采用「最低位优先法(Least Significant Digit First)」或者「最高位优先…

LangChain学习之路

何谓 LangChain?释放大语言模型潜能的利器 作为一种专为开发基于语言模型的应用而设计的框架,通过LangChain,我们不仅可以通过API调用如 ChatGPT、GPT-4、Llama 2 等大型语言模型,还可以实现更高级的功能。 我们相信&#xff0c…

二:Linux学习笔记(第一阶段)-- Linux命令

目录 Linux注意事项: Linux目录 Linux系统基础命令 1. 文件和目录操作 2. 文件查看和编辑 3. 文件权限和所有权 4. 系统信息 5. 网络命令 6. 文件查找 7. 压缩和解压缩 8. 系统管理 Linux注意事项: 严格区分大小写一切皆文件windows下的程序不…

嵌入式硬件重点(四)常用信号处理、放大电路、运算放大器(运放)基础篇

引言:在嵌入式硬件设计中,信号处理和放大电路是至关重要的组成部分。它们不仅影响系统的性能,还直接关系到数据的准确性和可靠性。随着嵌入式系统的广泛应用,对各种传感器和外部设备的信号进行有效处理显得尤为重要。 运算放大器&…

3D Gaussian Splatting代码详解(二):模型构建

3 模型构建 gaussians GaussianModel(dataset.sh_degree) 3.1 初始化函数 __init__ 构造函数 构造函数 __init__ 的主要作用是初始化 3D 高斯模型的各项参数和激活函数,用于生成 3D 空间中的高斯表示。 初始化球谐函数的参数: self.active_sh_degre…

自由学习记录(18)

动画事件的碰撞器触发 Physics 类的常用方法 RaycastHit hit; if (Physics.Raycast(origin, direction, out hit, maxDistance)) {Debug.Log("Hit: " hit.collider.name); } Physics.Raycast:从指定点向某个方向发射射线,检测是否与碰撞体…

[FE] React 初窥门径(四):React 组件的加载过程(render 阶段)

1. 回顾 前几篇文章中,我们采用了 VSCode 插件 CodeTour 来记录代码的执行过程, 并把相关的数据 .tour/ 放到了 github: thzt/react-tour 中。 截止到本文为之,我们总共记录了这些 code-tour, .tour/ ├── 2. 构建过程.tour ├─…

java毕业设计之基于Bootstrap的常州地方旅游管理系统的设计与实现(springboot)

项目简介 基于Bootstrap的常州地方旅游管理系统的设计与实现有下功能: 基于Bootstrap的常州地方旅游管理系统的设计与实现的主要使用者分为用户功能模块和管理员功能模块两大部分,用户可查看景点信息、景点资讯等,注册登录后可进行景点订票…

单链表OJ题(3):合并两个有序链表、链表分割、链表的回文结构

目录 一、合并两个有序链表 二、链表分割 三、链表的回文结构 u解题的总体思路: 合并两个有序链表:首先创建新链表的头节点(哨兵位:本质上是占位子),为了减少一些判断情况,简化操作。然后我们…

为数据集而生的 SQL 控制台

随着数据集的使用量急剧增加,Hugging Face 社区已经变成了众多数据集默认存放的仓库。每月,海量数据集被上传到社区,这些数据集亟需有效的查询、过滤和发现。 Dataset Monthly Creations 每个月在 Hugging Face Hub 创建的数据集 我们现在非常…

简易了解Pytorch中的@ 和 * 运算符(附Demo)

目录 1. 基本知识2. 3. * 1. 基本知识 在 PyTorch 中, 和 * 运算符用于不同类型的数学运算,具体是矩阵乘法和逐元素乘法 基本知识 运算符功能适用场景示例矩阵乘法(或点乘)用于执行线性代数中的矩阵乘法C A B,其中…

JavaScript知识点梳理及案例实践

1. Date对象 创建Date对象 //方法1:不指定参数 var nowd1new Date(); console.log(nowd1.toLocaleString( )); //方法2:参数为日期字符串 var d2new Date("2004/3/20 11:12"); console.log(d2.toLocaleString( )); var d3new Date("04/…

推荐一款Windows维护和修复工具包:RepairKit

RepairKit是一个综合性的Java开发的Windows修复和维护工具包。该工具包旨在为用户提供一个专用的系统修复工具,并快速访问一些操作系统功能及其他附带的电脑维护软件。 RepairKit 提供了一个简单有效的解决方案,用于维护PC的顺畅运行。它包括自动修复/清…

cocos开发QA

目录 TS相关foreach循环中使用return循环延迟动态获取类属性 Cocos相关属性检查器添加Enum属性实现不规则点击区域使用cc.RevoluteJoint的enable激活组件无效本地存储以及相关问题JSON.stringify(map)返回{}数据加密客户端复制文本使用客户端方法热更新LabelOutline.color is d…

大数据新视界 -- 大数据大厂之 Impala 性能优化:数据存储分区的艺术与实践(下)(2/30)

💖💖💖亲爱的朋友们,热烈欢迎你们来到 青云交的博客!能与你们在此邂逅,我满心欢喜,深感无比荣幸。在这个瞬息万变的时代,我们每个人都在苦苦追寻一处能让心灵安然栖息的港湾。而 我的…

记第一次本地编译seatunnel源码

拉取代码 git clone https://github.com/apache/seatunnel.git 使用版本 我们生产环境用的是2.3.5版本,所以基于2.3.5-release分支代码进行编译。 maven package过程 遇到的第一个问题:‘com.sun.tools.javac.tree.JCTree com.sun.tools.javac.tree…

6.1、属性动画

使用显式动画产生布局更新动画 1.旋转动画 只修改对应的属性 rotate({angle: this.angle}) 即可达到效果 动画效果 对应实现代码 @Entry @Component struct AnimationPage {@State angle:number = 0aboutToAppear() {