干货 | 通透理解Elasticsearch聚合

2023-11-10 10:50

本文主要是介绍干货 | 通透理解Elasticsearch聚合,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

Elasticsearch 最少必要知识实战教程直播回放

使用Elasticsearch的过程中,除了全文检索,或多或少会做统计操作,而做统计操作势必会使用Elasticsearch聚合操作。
类似mysql中group by的terms聚合用的最多,但当遇到复杂的聚合操作时,往往会捉襟见肘、不知所措…
这也是社区中聚合操作几乎每天都会被提问的原因。

本文基于官方文档,梳理出聚合的以下几个核心问题,目的:将Elasticsearch的聚合结合实际场景说透。

1、Elasticsearch聚合最直观展示

区别于倒排索引的key value的全文检索,聚合两个示例如下:
如下图,是基于某特定分类的聚合统计结果。
在这里插入图片描述
如下图:是基于月份的聚合统计结果。
在这里插入图片描述

2、Elasticsearch聚合定义

聚合有助于基于搜索查询提供聚合数据。 它基于称为聚合的简单构建块,可以组合以构建复杂的数据。
基本语法结构如下:

"aggregations" : {"<aggregation_name>" : {"<aggregation_type>" : {<aggregation_body>}[,"meta" : {  [<meta_data_body>] } ]?[,"aggregations" : { [<sub_aggregation>]+ } ]?}[,"<aggregation_name_2>" : { ... } ]*
}

3、Elasticsearch聚合分类

在这里插入图片描述

3.1 分类1:Metric聚合

基于一组文档进行聚合。所有的文档在一个检索集合里,文档被分成逻辑的分组。
类比Mysql中的: MIN(), MAX(), STDDEV(), SUM() 操作。

        单值Metric|v
SELECT AVG(price) FROM products多值Metric|          |v          v
SELECT MIN(price), MAX(price) FROM products
Metric聚合的DSL类比实现:
{"aggs":{"avg_price":{"avg":{"field":"price"}}}
}

Metric聚合操作对比:

AggregationElasticsearchMySQL
AvgYesYes
Cardinality——去重唯一值Yes (Sample based)Yes (Exact)——类似:distinct
Extended StatsYesStdDev bounds missing
Geo BoundsYesfor future blog post
Geo CentroidYesfor future blog post
MaxYesYes
PercentilesYesComplex SQL or UDF
Percentile RanksYesComplex SQL or UDF
ScriptedYesNo
StatsYesYes
Top Hits——很重要,易被忽视YesComplex
Value CountYesYes

其中,Top hits子聚合用于返回分组中Top X匹配结果集,且支持通过source过滤选定字段值。

分类2:Bucketing聚合

基于检索构成了逻辑文档组,满足特定规则的文档放置到一个桶里,每一个桶关联一个key。
类比Mysql中的group by操作,
Mysql使用举例:

           基于size 分桶 ...、
SELECT size COUNT(*) FROM products GROUP BY size +----------------------+
| size     |  COUNT(*) |
+----------------------+ 
| S        |   123     | <--- set of rows with size = S
| M        |   456     |
| ...      |  ...      |

bucket聚合的DSL类比实现:

{"query": {"match": {"title": "Beach"}},"aggs": {"by_size": {"terms": {"field": "size"}},"by_material": {"terms": {"field": "material"}}}
}

Bucketing聚合对比

AggregationElasticsearchMySQL
Childen——父子文档Yesfor future blog post
Date Histogram——基于时间分桶YesComplex
Date RangeYesComplex
FilterYesn/a (yes)
FiltersYesn/a (yes)
Geo DistanceYesfor future blog post
GeoHash gridYesfor future blog post
GlobalYesn/a (yes)
HistogramYesComplex
IPv4 RangeYesComplex
MissingYesYes
NestedYesfor future blog post
RangeYesComplex
Reverse NestedYesfor future blog post
SamplerYesComplex
Significant TermsYesNo
Terms——最常用YesYes

分类3:Pipeline聚合

对聚合的结果而不是原始数据集进行操作。
想象一下,你有一个日间交易的网上商店,想要了解所有产品的按照库存日期分组的平均价格。
在SQL中你可以写:

SELECT in_stock_since, AVG(price) FROM products GROUP BY in_stock_since。

ES使用举例:
以下Demo实现更复杂,按月统计销售额,并统计出月销售额>200的信息。
下一节详细给出DSL,不再重复。

分类4:Matrix聚合

ES6.4官网释义:此功能是实验性的,可在将来的版本中完全更改或删除。

3、Elasticsearch聚合完整举例

3.1 步骤1:动态Mapping,导入完整数据

POST _bulk
{"index":{"_index":"cars","_type":"doc","_id":"1"}}
{"name":"bmw","date":"2017-06-01", "color":"red", "price":30000}
{"index":{"_index":"cars","_type":"doc","_id":"2"}}
{"name":"bmw","date":"2017-06-30", "color":"blue", "price":50000}
{"index":{"_index":"cars","_type":"doc","_id":"3"}}
{"name":"bmw","date":"2017-08-11", "color":"red", "price":90000}
{"index":{"_index":"cars","_type":"doc","_id":"4"}}
{"name":"ford","date":"2017-07-15", "color":"red", "price":20000}
{"index":{"_index":"cars","_type":"doc","_id":"5"}}
{"name":"ford","date":"2017-07-01", "color":"blue", "price":40000}
{"index":{"_index":"cars","_type":"doc","_id":"6"}}
{"name":"bmw","date":"2017-08-01", "color":"green", "price":10000}
{"index":{"_index":"cars","_type":"doc","_id":"7"}}
{"name":"jeep","date":"2017-07-08", "color":"red", "price":110000}
{"index":{"_index":"cars","_type":"doc","_id":"8"}}
{"name":"jeep","date":"2017-08-25", "color":"red", "price":230000}

3.2 步骤2:确认Mapping

GET cars/_mapping

3.3 步骤3:Matric聚合实现

求车的平均价钱。

POST cars/_search
{"size": 0,"aggs": {"avg_grade": {"avg": {"field": "price"}}}
}

3.4 步骤4:bucket聚合与子聚合实现

按照车品牌分组,组间按照车颜色再二次分组。

POST cars/_search
{"size": 0,"aggs": {"name_aggs": {"terms": {"field": "name.keyword"},"aggs": {"color_aggs": {"terms": {"field": "color.keyword"}}}}}
}

3.5 步骤5:Pipeline聚合实现

按月统计销售额,并统计出总销售额大于200000的月份信息。

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

4、Elasticsearch聚合使用指南

认知前提:知道Elasticsearch聚合远比Mysql中种类要多,可实现的功能点要多。
遇到聚合问题,基于4个分类,查询对应的官网API信息。
以最常见场景为例:

  1. 确定是否是分组group by 操作,如果是,使用bucket聚合中的terms聚合实现;
  2. 确定是否是按照时间分组操作,如果是,使用bucket聚合中date_histogram的聚合实现;
  3. 确定是否是分组,组间再分组操作,如果是,使用bucket聚合中terms聚合内部再terms或者内部top_hits子聚合实现;
  4. 确定是否是求最大值、最小值、平均值等,如果是,使用Metric聚合对应的Max, Min,AVG等聚合实现;
  5. 确定是否是基于聚合的结果条件进行判定后取结果,如果是,使用pipline聚合结合其他聚合综合实现;

多尝试,多在kibana的 dev tool部分多验证。

参考:
1、https://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations.html
2、http://blog.ulf-wendel.de/2016/aggregation-features-elasticsearch-vs-mysql-vs-mongodb/
3、https://elasticsearch.cn/article/629

这里写图片描述
打造Elasticsearch基础、进阶、实战第一公众号!

这篇关于干货 | 通透理解Elasticsearch聚合的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/382185

相关文章

Java操作ElasticSearch的实例详解

《Java操作ElasticSearch的实例详解》Elasticsearch是一个分布式的搜索和分析引擎,广泛用于全文搜索、日志分析等场景,本文将介绍如何在Java应用中使用Elastics... 目录简介环境准备1. 安装 Elasticsearch2. 添加依赖连接 Elasticsearch1. 创

一文带你理解Python中import机制与importlib的妙用

《一文带你理解Python中import机制与importlib的妙用》在Python编程的世界里,import语句是开发者最常用的工具之一,它就像一把钥匙,打开了通往各种功能和库的大门,下面就跟随小... 目录一、python import机制概述1.1 import语句的基本用法1.2 模块缓存机制1.

深入理解C语言的void*

《深入理解C语言的void*》本文主要介绍了C语言的void*,包括它的任意性、编译器对void*的类型检查以及需要显式类型转换的规则,具有一定的参考价值,感兴趣的可以了解一下... 目录一、void* 的类型任意性二、编译器对 void* 的类型检查三、需要显式类型转换占用的字节四、总结一、void* 的

深入理解Redis大key的危害及解决方案

《深入理解Redis大key的危害及解决方案》本文主要介绍了深入理解Redis大key的危害及解决方案,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着... 目录一、背景二、什么是大key三、大key评价标准四、大key 产生的原因与场景五、大key影响与危

深入理解C++ 空类大小

《深入理解C++空类大小》本文主要介绍了C++空类大小,规定空类大小为1字节,主要是为了保证对象的唯一性和可区分性,满足数组元素地址连续的要求,下面就来了解一下... 目录1. 保证对象的唯一性和可区分性2. 满足数组元素地址连续的要求3. 与C++的对象模型和内存管理机制相适配查看类对象内存在C++中,规

基于MySQL Binlog的Elasticsearch数据同步实践

一、为什么要做 随着马蜂窝的逐渐发展,我们的业务数据越来越多,单纯使用 MySQL 已经不能满足我们的数据查询需求,例如对于商品、订单等数据的多维度检索。 使用 Elasticsearch 存储业务数据可以很好的解决我们业务中的搜索需求。而数据进行异构存储后,随之而来的就是数据同步的问题。 二、现有方法及问题 对于数据同步,我们目前的解决方案是建立数据中间表。把需要检索的业务数据,统一放到一张M

认识、理解、分类——acm之搜索

普通搜索方法有两种:1、广度优先搜索;2、深度优先搜索; 更多搜索方法: 3、双向广度优先搜索; 4、启发式搜索(包括A*算法等); 搜索通常会用到的知识点:状态压缩(位压缩,利用hash思想压缩)。

【生成模型系列(初级)】嵌入(Embedding)方程——自然语言处理的数学灵魂【通俗理解】

【通俗理解】嵌入(Embedding)方程——自然语言处理的数学灵魂 关键词提炼 #嵌入方程 #自然语言处理 #词向量 #机器学习 #神经网络 #向量空间模型 #Siri #Google翻译 #AlexNet 第一节:嵌入方程的类比与核心概念【尽可能通俗】 嵌入方程可以被看作是自然语言处理中的“翻译机”,它将文本中的单词或短语转换成计算机能够理解的数学形式,即向量。 正如翻译机将一种语言

【C++高阶】C++类型转换全攻略:深入理解并高效应用

📝个人主页🌹:Eternity._ ⏩收录专栏⏪:C++ “ 登神长阶 ” 🤡往期回顾🤡:C++ 智能指针 🌹🌹期待您的关注 🌹🌹 ❀C++的类型转换 📒1. C语言中的类型转换📚2. C++强制类型转换⛰️static_cast🌞reinterpret_cast⭐const_cast🍁dynamic_cast 📜3. C++强制类型转换的原因📝

深入理解RxJava:响应式编程的现代方式

在当今的软件开发世界中,异步编程和事件驱动的架构变得越来越重要。RxJava,作为响应式编程(Reactive Programming)的一个流行库,为Java和Android开发者提供了一种强大的方式来处理异步任务和事件流。本文将深入探讨RxJava的核心概念、优势以及如何在实际项目中应用它。 文章目录 💯 什么是RxJava?💯 响应式编程的优势💯 RxJava的核心概念