Elasticsearch 的DSL查询,聚合查询与多维度数据统计

news2024/11/13 16:31:32
文章目录
    • 搜索
    • 聚合
    • 高阶概念

搜索

即从一个索引下按照特定的字段或关键词搜索出符合用户预期的一个或者一堆cocument,然后根据文档的相关度得分,在返回的结果集里并根据得分对这些文档进行一定的排序。

聚合

根据业务需求,对文档中的某个或某几个字段进行数据的分组并做一些指标数据的统计分析,比如要计算一批文档中某个业务字段的总数,平均数,最大最小值等,都属于聚合的范畴。

以上两个概念后是理解下面实验的基础,如果是传统关系数据库mysql、oracle等存储的数据,也可以搜索和聚合,但是在数据聚合分析一块,毕竟不是它们的强项,而且需要在程序中做大量的处理,耗时费力,尤其是大数据量的情况下就有些力不从心了。

但在es中,由于内置了聚合统计的相关功能,只需要使用好它的语法即可达到几近实时的聚合统计,和搜索花费时间基本上没有太大差别,因此使用es很适合在数据量大的业务场景下做聚合统计与分析。

高阶概念

  • Buckets(桶/集合):满足特定条件的文档的集合
  • Metrics(指标):对桶内的文档进行统计计算(例如最小值,求和,最大值等)

在聚合统计分析中,使用很频繁的一个名词叫 aggs,它是聚合的关键词之一,下面就用实验来演示一下使用aggs进行数据聚合的多种场景。

1、实验准备数据,首先往es整合批量插入一些实验数据,这里我们以一个家电卖场的电视为背景进行模拟

设定文档中field的相关分词属性。

PUT http://192.168.56.235:9201/demo2

{
	"setting":{
		"index":{
			"number_of_shards":5,
			"number_of_replicats":1
		}
	},
	"mappings":{
		"sales":{
			"properties":{
				"price":{
					"type":"long"
				},
				"color":{
					"type":"keyword"
				},
				"brand":{
					"type":"keyword"
				},
				"sold_date":{
					"type":"date"
				}
			}
		}
	}
}

2、批量插入数据

POST http://192.168.56.235:9201/demo2/sales
		
{ "price" : 1000, "color" : "红色", "brand" : "长虹", "sold_date" : "2016-10-28" }
{ "price" : 2000, "color" : "红色", "brand" : "长虹", "sold_date" : "2016-11-05" }
{ "price" : 3000, "color" : "绿色", "brand" : "小米", "sold_date" : "2017-05-18" }
{ "price" : 1500, "color" : "蓝色", "brand" : "TCL", "sold_date" : "2017-07-02" }
{ "price" : 1200, "color" : "绿色", "brand" : "TCL", "sold_date" : "2018-08-19" }
{ "price" : 2000, "color" : "红色", "brand" : "长虹", "sold_date" : "2017-11-05" }
{ "price" : 8000, "color" : "红色", "brand" : "三星", "sold_date" : "2017-01-01" }
{ "price" : 2500, "color" : "蓝色", "brand" : "小米", "sold_date" : "2018-02-12" }

在这里插入图片描述
数据准备完毕
在这里插入图片描述
2、按照颜色分组统计各种颜色电视的数量

查询语法如下:

GET http://192.168.56.235:9201/demo2/sales/_search
{
	"size":0,
	"aggs":{
		"group_color":{
			"terms":{
				"field":"color"
			}
		}
	}
}

查询结果如下,这里简单对其中的几个参数和结果名称做一下说明。

在查询语句中:

  • size:0表示聚合查询的结果不需要返回中间的文档内容,
  • group_color 我们自定义的分组名字,最好是见名知意的

在返回结果中:

  • hits:{},这部分存放的是返回结果的基本统计结果,如果上面的size制指定了不为0,文档内容则会放在这个里面
  • buckets:存放聚合后的统计结果详细信息,以key-value的形式展现

在这里插入图片描述
3、按照颜色分组统计各种颜色电视的数量,并在此基础上,统计出各种颜色电视的平均价格

分析:

按照color去分bucket,可以拿到每个color bucket中的数量,这个仅仅只是一个bucket操作, doc_count其实只是es的bucket操作默认执行的一个内置metric。

在一个aggs执行的bucket操作(terms),平级的json结构下,再加一个aggs,这个第二个aggs内部,同样取个名字,执行一个metric操作,avg,对之前的每个bucket中的数据的指定的field、price
field,求一个平均值

就是一个metric,就是一个对一个bucket分组操作之后,对每个bucket都要执行的一个metric,也可以理解成功嵌套聚合,在es中获取到某个指标的数据后,继续对这个指标的数据进行其他聚合分析也被叫做下钻

该需求查询语句如下:

{
	"size":0,
	"aggs":{
		"group_color":{
			"terms":{
				"field":"color"
			},
			"aggs":{
				"avg_color_price":{
					"avg":{
						"field":"price"
					}
				}
			}
		}
	}
}

返回结果如下,通过结果可以很清晰的看出来,在颜色统计分析的基础上,每一个{}里面还增加了一个指标,即自定义的计算平均值的avg_color_price,这个查询几乎是毫秒级的,基本没有延迟,如果转化为sql查询应该是这样的:

select avg(price) from tvs.sales group by color

在这里插入图片描述
4、根据颜色分组,求出每种颜色的电视价格的最大值,最小值,平均值

{
	"size":0,
	"aggs":{
		"group_by_color":{
			"terms":{
				"field":"color"
			},
			"aggs":{
				"max_price":{
					"max":{
						"field":"price"
					}
				},
				"min_price":{
					"min":{
						"field":"price"
					}
				},
				"avg_price":{
					"avg":{
						"field":"price"
					}
				}
			}
		}
	}
}

所得结果如下:

{
    "took": 4,
    "timed_out": false,
    "_shards": {
        "total": 5,
        "successful": 5,
        "skipped": 0,
        "failed": 0
    },
    "hits": {
        "total": 7,
        "max_score": 0,
        "hits": []
    },
    "aggregations": {
        "group_by_color": {
            "doc_count_error_upper_bound": 0,
            "sum_other_doc_count": 0,
            "buckets": [
                {
                    "key": "红色",
                    "doc_count": 4,
                    "max_price": {
                        "value": 8000
                    },
                    "min_price": {
                        "value": 1000
                    },
                    "avg_price": {
                        "value": 3250
                    }
                },
                {
                    "key": "蓝色",
                    "doc_count": 2,
                    "max_price": {
                        "value": 2500
                    },
                    "min_price": {
                        "value": 1500
                    },
                    "avg_price": {
                        "value": 2000
                    }
                },
                {
                    "key": "绿色",
                    "doc_count": 1,
                    "max_price": {
                        "value": 1200
                    },
                    "min_price": {
                        "value": 1200
                    },
                    "avg_price": {
                        "value": 1200
                    }
                }
            ]
        }
    }
}

5、按照不同的价格区间对电视进行划分,并求出每个价格区间的电视的平均价格

在es中根据区间间隔划分,有一个叫做 histogram的语法可以帮助我们执行,类似于terms,也是进行bucket分组操作,接收一个field,按照这个field的值的各个范围区间,进行bucket分组操作。

“histogram”:{
	“field”: “price”,
	“interval”: 2000
},

  • interval:2000,划分范围,0 ~ 2000,2000 ~ 4000,4000 ~ 6000,6000 ~ 8000,8000 ~ 10000,buckets
  • 根据price的值,比如2500,看落在哪个区间内,比如2000 ~ 4000,此时就会将这条数据放入2000 ~ 4000对应的那个bucket中
  • bucket划分的方法terms,将field值相同的数据划分到一个bucket中
  • bucket有了之后,一样的,去对每个bucket执行avg,count,sum,max,min,等各种metric操作,聚合分析
{
	"size":0,
	"aggs":{
		"interval_price":{
			"histogram":{
				"field":"price",
				"interval":2000
				},
				"aggs":{
					"revenue":{
					"avg":{
						"field":"price"
					}
				}
			}
		}
	}	
}

查询的结果如下:可以看到,按照2000一个等级将所有电视的价格划分在不同的区间了,并将每个区间的价格平均值统计了出来

{
    "took": 7,
    "timed_out": false,
    "_shards": {
        "total": 5,
        "successful": 5,
        "skipped": 0,
        "failed": 0
    },
    "hits": {
        "total": 7,
        "max_score": 0,
        "hits": []
    },
    "aggregations": {
        "interval_price": {
            "buckets": [
                {
                    "key": 0,
                    "doc_count": 3,
                    "revenue": {
                        "value": 1233.3333333333333
                    }
                },
                {
                    "key": 2000,
                    "doc_count": 3,
                    "revenue": {
                        "value": 2166.6666666666665
                    }
                },
                {
                    "key": 4000,
                    "doc_count": 0,
                    "revenue": {
                        "value": null
                    }
                },
                {
                    "key": 6000,
                    "doc_count": 0,
                    "revenue": {
                        "value": null
                    }
                },
                {
                    "key": 8000,
                    "doc_count": 1,
                    "revenue": {
                        "value": 8000
                    }
                }
            ]
        }
    }
}

6、按照不同的时间区间对电视进行划分,并求出每个价格区间的电视的平均价格

date histogram,按照我们指定的某个date类型的日期field,以及日期interval,按照一定的日期间隔,去划分bucket,这个概念的理解和上一个有点类似,可以对照理解。

date interval = 1 month
2017-01-01~2017-01-31,就是一个bucket
2017-02-01~2017-02-28,就是一个bucket

然后会去扫描每个数据的date field,判断date落在哪个bucket中,就将其放入那个bucket
2017-01-05,就将其放入2017-01-01~2017-01-31,就是一个bucket

min_doc_count:即使某个日期interval,2017-01-01~2017-01-31中,一条数据都没有,那么这个区间也是要返回的,不然默认是会过滤掉这个区间的
extended_bounds,min,max:划分bucket的时候,会限定在这个起始日期,和截止日期内

根据上述分析我们构建查询语句

{
	"size":0,
	"aggs":{
		"sales":{
			"date_histogram":{
				"field":"sold_date",
				"interval":"month",
				"format":"yyyy-MM-dd",
				"min_doc_count":0,
				"extended_bounds":{
					"min":"2017-01-01",
					"max":"2018-12-31"
				}
			}
		}
	}
}


返回结果如下,按照月份,将指定区间内各个月份的数量做了统计
在这里插入图片描述
当然,如果我们觉得按照月份统计粒度太细,也可以根据季度对数据进行统计,只需要将month换成quarter即可,查询语法如下:

{
	"size":0,
	"aggs":{
		"sales":{
			"date_histogram":{
				"field":"sold_date",
				"interval":"quarter",
				"format":"yyyy-MM-dd",
				"min_doc_count":0,
				"extended_bounds":{
					"min":"2017-01-01",
					"max":"2018-12-31"
				}
			}
		}
	}
}

查询结果如下:
在这里插入图片描述

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

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

相关文章

【源码+文档+调试讲解】营业厅宽带系统设计与实现

摘 要 现代经济快节奏发展以及不断完善升级的信息化技术,让传统数据信息的管理升级为软件存储,归纳,集中处理数据信息的管理方式。本营业厅宽带系统就是在这样的大环境下诞生,其可以帮助管理者在短时间内处理完毕庞大的数据信息&…

Action部署在线上写文章

原文:https://blog.c12th.cn/archives/32.html 前言 之前分别出了 Hexo 和 Hugo 的 Action搭建教程,相当于伪动态,可以在线上写文章了;不过对于喜欢魔改的同学就不太友好了qwq 教程 github.dev 确保在配置过程中能访问Github &…

学工系统学生家庭情况登记功能概述

智慧校园学工系统中的“学生家庭情况”模块主要用于收集和管理学生的家庭背景信息,以便学校更好地了解学生的情况,并据此提供相应的支持和服务。该模块通常包括以下几个方面: 基本信息录入:支持录入学生的家庭成员信息&#xff0c…

ocaml精解【1】

文章目录 概述简介一、基本概述二、开发工具三、语言特性四、应用场景五、未来展望 windows下安装基础 参考文献 概述 简介 OCaml(Objective Caml)是Caml编程语言的主要实现,由Xavier Leroy、Jrme Vouillon、Damien Doligez、Didier Rmy等人…

一款免费强大的电脑锁屏工具,中文绿色免安装

这款软件主要特点是锁屏后不显示密码输入框,直接输入密码即可解锁。 ScreenBlur是一款功能强大的电脑屏幕锁软件,主要用于保护用户的隐私和数据安全。该软件的主要功能包括自动锁屏、隐藏桌面、加密锁机等。 功能特点 自动锁屏:用户可以设…

C语言之unsigned long long与struct相互转换实例(五十六)

简介: CSDN博客专家,专注Android/Linux系统,分享多mic语音方案、音视频、编解码等技术,与大家一起成长! 新书发布:《Android系统多媒体进阶实战》🚀 优质专栏: Audio工程师进阶系列…

数学希腊符号

1、Α α alpha /a:lf/ 阿尔法 2、Β β beta /bet/ 贝塔 3、Γ γ gamma /ga:m/ 伽马 4、Δ δ delta /delt/ 德尔塔 5、Ε ε epsilon /epsilon/ 伊普西龙 6、Ζ ζ zeta /zat/ 截塔 7、Η η eta /eit/ 艾塔 8、Θ θ thet /θit/ 西塔 9、Ι ι iot /aiot/ 约塔 10、Κ κ …

ADHD儿童康复的灯塔,专业与爱共筑希望之桥

在自闭症及注意缺陷多动障碍(ADHD)儿童教育领域,专业的康复学校扮演着至关重要的角色。这些学校不仅为孩子们提供科学的康复训练,还致力于帮助他们融入社会,实现自我价值。 以星启帆自闭症儿童康复机构为例&#xff0c…

【系统架构设计师】二十四、安全架构设计理论与实践③

目录 五、网络安全体系架构设计 5.1 OSI安全架构 5.2 认证框架 5.3 访问控制框架 5.4 机密性框架 5.5 完整性框架 5.6 抗抵赖框架 往期推荐 五、网络安全体系架构设计 5.1 OSI安全架构 OSI定义了7层协议,其中除第5层(会话层)外,每一层均能提供相…

NetAssist免费下载使用

这种TCPUDP的局域网工具有很多,但是找起来很麻烦,在微信小程序里面发现了一个“TCPUDP局域网小助手”的工具,打开即用非常方便, 打开之后长这样 能下载电脑端NetAssist

使用RK Docker环境编译RK SDK

文章目录 前言Docker介绍实验环境获取RK Docker镜像加载RK Docker镜像使用RK Docker环境编译SDK其它 前言 作为一名嵌入式Linux的学习者,目前编译各种平台,用的都是同一个编译机(Ubuntu虚拟机)。之前一直在折腾全志,所…

GraphRag本地测试

测试环境:win10 python3.11.9 graphRAG的安装还是很简单的,直接pip pip install graphrag 但要注意,官方说了需要 python3.10-3.12 安装完成后,建立一个文件夹,存放你的知识数据,目前graphRAG仅支持txt和…

Mysql错误:InnoDB: page_cleaner

今天一大早就收到同事昨晚发过来的信息:某省份的充电桩在昨晚22点到23点期间大量挂单即充电不能结算。首先想到的就是订单服务挂了,可查了数据一切正常。所以继续早跑,等上班回公司再查查原因。 来到公司查看了昨晚的项目日记情况&#xff0c…

使用Markdown画图

大部分 Markdown 编辑器的画图功能都是基于 mermaid 的,因此我们先介绍下它。 ‍ 什么是 mermaid ​ ‍ mermaid 是一个开源的项目,旨在通过纯文本的形式来画图,支持流程图,时序图,甘特图,类图&#x…

Arduino PID库 (1)– 简介

Arduino PID库 (1)– 简介 pid内容索引-CSDN博客pid术语及整定原则参考:手把手教你看懂并理解Arduino PID控制库——引子)库的改进QuickPID-sTune库 原文地址 随着新的Arduino PID库的发布,最后一个库虽然很可靠,但…

浅谈AC自动机算法(c++)

文章目录 自动机一些简单的自动机: AC 自动机字典树构建失配指针构建指针 [HNOI2006] 最短母串问题题目描述输入格式输出格式样例 #1样例输入 #1样例输出 #1 提示思路AC代码 「一本通 2.4 例 1」Keywords SearchAC代码 自动机 自动机是什么? 自动机的作…

Linux小组件:gcc

gcc 是C语言的编译器,在Linux下我们也用这个编译C语言 安装gcc sudo apt install build-essential 查看gcc版本信息 gcc --version 有时候会出现代码编译不过去的问题,通常可能是gcc的编译标准太低,不支持某些写法 比如在很多旧的编译标…

rk3588 部署yolov8.rknn

本文从步骤来记录在rk3588芯片上部署yolov8模型 主机:windows10 VMware Workstation 16 Pro 硬件:RK3588 EVB板 模型: RK3588.rknn 软件开发环境: c cmake step1: 主机上执行: 将rknn_model_zoo 工程文件下载…

spring:标签property

标签property对应于bean类公开的JavaBean setter方法。标签property的属性中,name为属性名,type为“”引号里面的类型,use为是否必须出现。 1.ref引用一个已经存在的对象,value创建一个新的对象 2.value可以赋一些简单类型的值,…

【MySQL】常用数据类型

目录 数据类型 数据类型分类 数值类型 tinyint类型 bit类型 小数类型 float decimal 字符串类型 char varchar 日期和时间类型 enum和set 数据类型 数据类型分类 数值类型 tinyint类型 tinyint类型只占用一个字节类似于编程语言中的字符char。有带符号和无符号两…