【ElasticSearch从入门到放弃系列 十一】Elasticsearch常用查询方式讨论及实践(五)

本文涉及的产品
检索分析服务 Elasticsearch 版,2核4GB开发者规格 1个月
简介: 【ElasticSearch从入门到放弃系列 十一】Elasticsearch常用查询方式讨论及实践(五)

聚合查询

聚合查询实际上是一种统计和计算,按照官方文档的解释共有四类

  • Metric(指标): 指标分析类型,如计算最大值、最小值、平均值等等 (对桶内的文档进行聚合分析的操作)
  • Bucket(桶): 分桶类型,类似SQL中的GROUP BY语法 (满足特定条件的文档的集合)
  • Pipeline(管道): 管道分析类型,基于上一级的聚合分析结果进行在分析
  • Matrix(矩阵): 矩阵分析类型(聚合是一种面向数值型的聚合,用于计算一组文档字段中的统计信息)

一般聚合的写法如下:

"aggregations" : {
    "<aggregation_name>" : {                                 <!--聚合的名字 -->
        "<aggregation_type>" : {                               <!--聚合的类型 -->
            <aggregation_body>                                 <!--聚合体:对哪些字段进行聚合 -->
        }
        [,"meta" : {  [<meta_data_body>] } ]?               <!--元 -->
        [,"aggregations" : { [<sub_aggregation>]+ } ]?   <!--在聚合里面在定义子聚合 -->
    }
    [,"<aggregation_name_2>" : { ... } ]*                     <!--聚合的名字 -->
}

其中aggregations 也可简写为 aggs,虽然Elasticsearch有四种聚合方式,但在一般实际开发中,用到的比较多的就是Metric和Bucket。其实从功能上只有前两类:一类是进行数学计算聚合使用的【max、min、avg、sum、stats 】,类似sql里的函数,也就是ES里的统计聚合,另一类则是进行分组聚合使用的,类似sql里的group,也就是ES里的桶聚合。剩余的两类就是程序上的辅助聚合方式,一种是管道二次处理,一种似是分桶同时处理统计计算

桶(bucket)

  • 简单来说桶就是满足特定条件的文档的集合。*
  • 当聚合开始被执行,每个文档里面的值通过计算来决定符合哪个桶的条件,如果匹配到,文档将放入相应的桶并接着开始聚合操作。
  • 桶也可以被嵌套在其他桶里面。

指标(metric)

  • 桶能让我们划分文档到有意义的集合,但是最终我们需要的是对这些桶内的文档进行一些指标的计算。分桶是一种达到目的地的手段:它提供了一种给文档分组的方法来让我们可以计算感兴趣的指标。
  • 大多数指标是简单的数学运算(如:最小值、平均值、最大值、汇总),这些是通过文档的值来计算的。

接下来我们分别实践一下。

桶聚合

我们先来看一个桶聚合,例如我们想要进行如下聚合【按照年龄聚合,0-10,10-20,20-30】,查询语句如下:

{
  "size": 0, 
  "aggs": {
    "user_age_info": {
      "range": {
        "field": "age",
        "ranges": [
          {
            "from": 0,
            "to": 10
          },
          {
            "from": 11,
            "to": 20
          },
          {
            "from": 21,
            "to": 30
          }
        ]
      }
    }
  }
}

返回结果为:

{
    "took": 2,
    "timed_out": false,
    "_shards": {
        "total": 3,
        "successful": 3,
        "skipped": 0,
        "failed": 0
    },
    "hits": {
        "total": {
            "value": 15,
            "relation": "eq"
        },
        "max_score": null,
        "hits": []
    },
    "aggregations": {
        "user_age_info": {
            "buckets": [
                {
                    "key": "0.0-10.0",
                    "from": 0.0,
                    "to": 10.0,
                    "doc_count": 4
                },
                {
                    "key": "11.0-20.0",
                    "from": 11.0,
                    "to": 20.0,
                    "doc_count": 7
                },
                {
                    "key": "21.0-30.0",
                    "from": 21.0,
                    "to": 30.0,
                    "doc_count": 4
                }
            ]
        }
    }
}

指标聚合

指标聚合分为两种,分别是单值分析和多值分析,各自有几个查询关键字:

  • 单值分析只输出一个分析结果:min,max,avg,sum,cardinality
  • 多值分析输出多个分析结果:stats, extended_stats, percentile, percentile_rank, top hits
    统计计算这里我们分别使用一下以上几种方式进行分析,最后再结合分组进行一些复合的统计计算查询。

单值分析

我们分别带入场景来进行单值指标的聚合分析。

max

这里我们想查询,所有员工信息中,【年龄最大的员工】,则查询参数为:

{
    "size":0,
    "aggs" : {
        "max_age" : { "max" : { "field" : "age" } }
    }
}

返回为:

{
    "took": 15,
    "timed_out": false,
    "_shards": {
        "total": 3,
        "successful": 3,
        "skipped": 0,
        "failed": 0
    },
    "hits": {
        "total": {
            "value": 15,
            "relation": "eq"
        },
        "max_score": null,
        "hits": []
    },
    "aggregations": {
        "max_age": {
            "value": 28.0
        }
    }
}

min

这里我们想查询,所有员工信息中,【年龄最小的员工】,则查询参数为:

{
    "size":0,
    "aggs" : {
        "min_age" : { "min" : { "field" : "age" } }
    }
}

返回结果为:

{
    "took": 6,
    "timed_out": false,
    "_shards": {
        "total": 3,
        "successful": 3,
        "skipped": 0,
        "failed": 0
    },
    "hits": {
        "total": {
            "value": 15,
            "relation": "eq"
        },
        "max_score": null,
        "hits": []
    },
    "aggregations": {
        "min_age": {
            "value": 8.0
        }
    }
}

avg

这里我们想查询,所有员工信息中,【平均年龄是多少】,则查询参数为:

{
    "size":0,
    "aggs" : {
        "avg_age" : { "avg" : { "field" : "age" } }
    }
}

返回结果为:

{
    "took": 19,
    "timed_out": false,
    "_shards": {
        "total": 3,
        "successful": 3,
        "skipped": 0,
        "failed": 0
    },
    "hits": {
        "total": {
            "value": 15,
            "relation": "eq"
        },
        "max_score": null,
        "hits": []
    },
    "aggregations": {
        "avg_age": {
            "value": 18.0
        }
    }
}

sum

这里我们想查询,所有员工信息中,【年龄总和为多大】,则查询参数为:

{
    "size":0,
    "aggs" : {
        "sun_age" : { "sum" : { "field" : "age" } }
    }
}

返回结果为:

{
    "took": 9,
    "timed_out": false,
    "_shards": {
        "total": 3,
        "successful": 3,
        "skipped": 0,
        "failed": 0
    },
    "hits": {
        "total": {
            "value": 15,
            "relation": "eq"
        },
        "max_score": null,
        "hits": []
    },
    "aggregations": {
        "sun_age": {
            "value": 270.0
        }
    }
}

cardinality

cardinality 求唯一值,即不重复的字段有多少(相当于mysql中的distinct),我们现在查询所有员工信息共有多少种年龄,请求参数为:

{
    "size":0,
    "aggs" : {
        "age_count" : { "cardinality" : { "field" : "age" } }
    }
}

返回值为:

{
    "took": 22,
    "timed_out": false,
    "_shards": {
        "total": 3,
        "successful": 3,
        "skipped": 0,
        "failed": 0
    },
    "hits": {
        "total": {
            "value": 15,
            "relation": "eq"
        },
        "max_score": null,
        "hits": []
    },
    "aggregations": {
        "sex_count": {
            "value": 3
        }
    }
}

共有8、18、28三种年龄

多值分析

多值分析包括以下关键字stats,extended_stats,percentile,percentile_rank,top hits,我们一个一个讨论下

stats

我想统计所有员工年龄的各种单值分析状态,可以使用stats,请求参数如下:

{
    "size":0,
    "aggs" : {
        "age_stats" : { "stats" : { "field" : "age" } }
    }
}

返回值为:

{
    "took": 3,
    "timed_out": false,
    "_shards": {
        "total": 3,
        "successful": 3,
        "skipped": 0,
        "failed": 0
    },
    "hits": {
        "total": {
            "value": 15,
            "relation": "eq"
        },
        "max_score": null,
        "hits": []
    },
    "aggregations": {
        "age_stats": {
            "count": 15,
            "min": 8.0,
            "max": 28.0,
            "avg": 18.0,
            "sum": 270.0
        }
    }
}

Percentiles

对指定字段的值按从小到大累计每个值对应的文档数的占比,返回指定占比比例对应的值。默认按照[ 1, 5, 25, 50, 75, 95, 99 ]来统计,我们想统计各个年龄百分区间内员工的数量:

{
    "size":0,
    "aggs" : {
        "age_percentiles" : { "percentiles" : { "field" : "age" } }
    }
}

返回结果为:

{
    "took": 15,
    "timed_out": false,
    "_shards": {
        "total": 3,
        "successful": 3,
        "skipped": 0,
        "failed": 0
    },
    "hits": {
        "total": {
            "value": 15,
            "relation": "eq"
        },
        "max_score": null,
        "hits": []
    },
    "aggregations": {
        "age_percentiles": {
            "values": {
                "1.0": 8.0,
                "5.0": 8.0,
                "25.0": 10.5,
                "50.0": 18.0,
                "75.0": 25.5,
                "95.0": 28.0,
                "99.0": 28.0
            }
        }
    }
}

可以理解为99%的员工都小于等于28岁。这个按百分值进行强制分布

Percentile Ranks

上面是通过百分比求文档值,这里通过文档值求百分比,请求参数为:

{
    "size":0,
    "aggs" : {
        "age_percentile_ranks" : { "percentile_ranks" : { "field" : "age","values" : [8, 18,28] } }
    }
}

返回值为:

{
    "took": 11,
    "timed_out": false,
    "_shards": {
        "total": 3,
        "successful": 3,
        "skipped": 0,
        "failed": 0
    },
    "hits": {
        "total": {
            "value": 15,
            "relation": "eq"
        },
        "max_score": null,
        "hits": []
    },
    "aggregations": {
        "age_percentile_ranks": {
            "values": {
                "8.0": 20.0,
                "18.0": 66.66666666666666,
                "28.0": 100.0
            }
        }
    }
}

age<=8岁的占比20%,感觉两种百分比的形式还是不是非常准确的,关于查询的准确性我们之后再另行讨论。

分桶指标复合分析

这里我们来依据年龄段进行,分析,想要进行如下聚合【按照年龄聚合,0-20,20-40】,并且对每个年龄段内的年龄进行平均值计算。

{
  "size": 0, 
  "aggs": {
    "user_age_info": {
      "range": {
        "field": "age",
        "ranges": [
          {
            "from": 0,
            "to": 20
          },
          {
            "from": 21,
            "to": 40
          }
        ]
      },
       "aggs": {
            "age_avg": {
              "avg": {
                "field": "age"
              }
            }
          }
    }
  }
}

返回值为:

{
    "took": 7,
    "timed_out": false,
    "_shards": {
        "total": 3,
        "successful": 3,
        "skipped": 0,
        "failed": 0
    },
    "hits": {
        "total": {
            "value": 15,
            "relation": "eq"
        },
        "max_score": null,
        "hits": []
    },
    "aggregations": {
        "user_age_info": {
            "buckets": [
                {
                    "key": "0.0-20.0",
                    "from": 0.0,
                    "to": 20.0,
                    "doc_count": 11,
                    "age_avg": {
                        "value": 14.363636363636363
                    }
                },
                {
                    "key": "21.0-40.0",
                    "from": 21.0,
                    "to": 40.0,
                    "doc_count": 4,
                    "age_avg": {
                        "value": 28.0
                    }
                }
            ]
        }
    }
}

0到20岁之间共4个8岁,7个11岁,平均值为14.36岁。总而言之,桶聚合一般关键字为keyword,用来分类。

总结

以上就是周一到周四,四天的早上起大早的成果,将近3万字的成果,分别为普通模式、复合模式以及聚合模式,当然更复杂的将这几种融合起来的查询方式也是有的,等待后续的探索和学习啦。

相关实践学习
使用阿里云Elasticsearch体验信息检索加速
通过创建登录阿里云Elasticsearch集群,使用DataWorks将MySQL数据同步至Elasticsearch,体验多条件检索效果,简单展示数据同步和信息检索加速的过程和操作。
ElasticSearch 入门精讲
ElasticSearch是一个开源的、基于Lucene的、分布式、高扩展、高实时的搜索与数据分析引擎。根据DB-Engines的排名显示,Elasticsearch是最受欢迎的企业搜索引擎,其次是Apache Solr(也是基于Lucene)。 ElasticSearch的实现原理主要分为以下几个步骤: 用户将数据提交到Elastic Search 数据库中 通过分词控制器去将对应的语句分词,将其权重和分词结果一并存入数据 当用户搜索数据时候,再根据权重将结果排名、打分 将返回结果呈现给用户 Elasticsearch可以用于搜索各种文档。它提供可扩展的搜索,具有接近实时的搜索,并支持多租户。
相关文章
|
28天前
|
存储 运维 监控
金融场景 PB 级大规模日志平台:中信银行信用卡中心从 Elasticsearch 到 Apache Doris 的先进实践
中信银行信用卡中心每日新增日志数据 140 亿条(80TB),全量归档日志量超 40PB,早期基于 Elasticsearch 构建的日志云平台,面临存储成本高、实时写入性能差、文本检索慢以及日志分析能力不足等问题。因此使用 Apache Doris 替换 Elasticsearch,实现资源投入降低 50%、查询速度提升 2~4 倍,同时显著提高了运维效率。
金融场景 PB 级大规模日志平台:中信银行信用卡中心从 Elasticsearch 到 Apache Doris 的先进实践
|
1月前
|
数据采集 人工智能 运维
从企业级 RAG 到 AI Assistant,阿里云Elasticsearch AI 搜索技术实践
本文介绍了阿里云 Elasticsearch 推出的创新型 AI 搜索方案。
227 5
|
2月前
|
数据采集 人工智能 运维
从企业级 RAG 到 AI Assistant,阿里云Elasticsearch AI 搜索技术实践
本文介绍了阿里云 Elasticsearch 推出的创新型 AI 搜索方案
210 3
从企业级 RAG 到 AI Assistant,阿里云Elasticsearch AI 搜索技术实践
|
3月前
|
存储 JSON Java
ELK 圣经:Elasticsearch、Logstash、Kibana 从入门到精通
ELK是一套强大的日志管理和分析工具,广泛应用于日志监控、故障排查、业务分析等场景。本文档将详细介绍ELK的各个组件及其配置方法,帮助读者从零开始掌握ELK的使用。
|
4月前
|
存储 JSON 监控
大数据-167 ELK Elasticsearch 详细介绍 特点 分片 查询
大数据-167 ELK Elasticsearch 详细介绍 特点 分片 查询
79 4
|
4月前
|
存储 Java API
Elasticsearch 7.8.0从入门到精通
这篇文章详细介绍了Elasticsearch 7.8.0的安装、核心概念(如正排索引和倒排索引)、RESTful风格、各种索引和文档操作、条件查询、聚合查询以及在Spring Boot中整合Elasticsearch的步骤和示例。
234 1
Elasticsearch 7.8.0从入门到精通
|
4月前
|
自然语言处理 搜索推荐 Java
SpringBoot 搜索引擎 海量数据 Elasticsearch-7 es上手指南 毫秒级查询 包括 版本选型、操作内容、结果截图(一)
SpringBoot 搜索引擎 海量数据 Elasticsearch-7 es上手指南 毫秒级查询 包括 版本选型、操作内容、结果截图
82 0
|
4月前
|
存储 自然语言处理 搜索推荐
SpringBoot 搜索引擎 海量数据 Elasticsearch-7 es上手指南 毫秒级查询 包括 版本选型、操作内容、结果截图(二)
SpringBoot 搜索引擎 海量数据 Elasticsearch-7 es上手指南 毫秒级查询 包括 版本选型、操作内容、结果截图(二)
69 0
|
4月前
|
消息中间件 监控 关系型数据库
MySQL数据实时同步到Elasticsearch:技术深度解析与实践分享
在当今的数据驱动时代,实时数据同步成为许多应用系统的核心需求之一。MySQL作为关系型数据库的代表,以其强大的事务处理能力和数据完整性保障,广泛应用于各种业务场景中。然而,随着数据量的增长和查询复杂度的提升,单一依赖MySQL进行高效的数据检索和分析变得日益困难。这时,Elasticsearch(简称ES)以其卓越的搜索性能、灵活的数据模式以及强大的可扩展性,成为处理复杂查询需求的理想选择。本文将深入探讨MySQL数据实时同步到Elasticsearch的技术实现与最佳实践。
306 0
|
5月前
|
数据可视化 Java Windows
Elasticsearch入门-环境安装ES和Kibana以及ES-Head可视化插件和浏览器插件es-client
本文介绍了如何在Windows环境下安装Elasticsearch(ES)、Elasticsearch Head可视化插件和Kibana,以及如何配置ES的跨域问题,确保Kibana能够连接到ES集群,并提供了安装过程中可能遇到的问题及其解决方案。
Elasticsearch入门-环境安装ES和Kibana以及ES-Head可视化插件和浏览器插件es-client

热门文章

最新文章