4.【Elasticsearch】Elasticsearch从入门到放弃-聚合概述

本文涉及的产品
检索分析服务 Elasticsearch 版,2核4GB开发者规格 1个月
简介: 【Elasticsearch】Elasticsearch从入门到放弃-聚合概述

之前项目增加了一个新需求,用户商品搜索,在搜索引擎完成搜索后,在展示结果中需要进行进一步的筛选,而筛选的维度需要根据当前的搜索结果进行汇总。由于之前看过es的书,基于之前学习的内容,在项目实战中做了总结。

前文如上:

9.工具使用:Elasticsearch从入门到放弃(1)-Elasticsearch概念篇

10.工具使用:Elasticsearch从入门到放弃(2)-相关性算法

11.工具使用:Elasticsearch从入门到放弃(3)-权重及打分 (qq.com)


文档摘自《Elasticsearch搜索引擎构建入门与实战》

1.背景

当用户使用搜索引擎完成搜索后,在展示结果中需要进行进一步的筛选,而筛选的维度需要根据当前的搜索结果进行汇总,这就用到了聚合技术。聚合的需求在很多应用程序中都有所体现,例如在京东App中搜索“咸鸭蛋”,然后单击搜索界面中的“筛选”按钮,在弹出的界面中可以对当前的搜索结果进行进一步的过滤。例如,可以从价格区间、品牌、分类、枚数等维度分别进行筛选,(具体筛选条件是从第一步搜索条件中得到的)如图所示。

网络异常,图片无法展示
|
ES支持丰富的聚合操作, 不仅可以使用聚合功能对文档进行计数,还可以计算文档字段的平均值、最大值和最小值等。ES还提供了桶聚合的功能,以便于对多维度数据进行聚合。 接下来结合实例介绍这些内容。另外,如果希望搜索结果和聚合结果一起返回,其中绕不开的一个主题就是分页和排序,本章也会对这两部内容进行介绍。

为方便介绍,下面重新定义酒店的索引。

网络异常,图片无法展示
|
接着向索引中写入示例数据,具体如下:

网络异常,图片无法展示
|

2. 聚合指标

2.1 常见的统计指标

在搜索聚合时,用户可能会关注字段的相关统计信息,例如平均值、最大值、最小值及加和值等。例如,用户在使用一个二手房交易搜索引擎进行搜索时,可能会关注当前城市各个区域的房产平均价格。再例如,用户在搜索酒店时,也可能会关注附近各个区域酒店的最低价格。如图7.2所示,左图为在链家App的地图模式,可以搜索到当前位置附近的二手房平均交易价格;右图为携程App的地图模式,可以搜索到当前位置附近最低价格的酒店。

ES聚合请求的地址也是索引的搜索地址,可以使用aggs子句封装聚合请求。当使用avg子句进行平均值的聚合时,可以在avg子句中指定聚合的字段。在默认情况下,查询将匹配所有文档,如果不需要返回匹配的文档信息,最好将返回的文档个数设置为0。这样既可以让结果看起来更整洁,又可以提高查询速度。下面的DSL将查询所有酒店的平均价格并且不返回匹配的文档信息。

网络异常,图片无法展示
|

在上面的搜索结果中,索引中的5个文档全部命中,由于DSL设置size为0,所以命中文档的信息没有显示。在搜索结果的aggregations子句中存储着聚合结果,其中my_agg是聚合的名称,其对应的value值就是具体聚合结果,即酒店的平均价格。如果聚合的指标字段不是ES的基本类型,例如object类型,则可以使用点运算符进行引用。下面的DSL演示了

网络异常,图片无法展示
|
为了避免多次请求,ES还提供了stats聚合。stats聚合可以将对应字段的最大值、最小值、平均值及加和值一起计算并返回计算结果。下面的DSL展示了stats的用法。

网络异常,图片无法展示
|

以下代码演示了在Java中使用stats聚合的逻辑。

网络异常,图片无法展示
|

2.2 空值处理

在索引中的一部分文档很可能其某些字段是缺失的,在介绍空值处理之前,首先介绍ES聚合查询提供的value_count聚合,该聚合用于统计字段非空值的个数。以下示例使用value_count聚合统计了price字段中非空值的个数。

网络异常,图片无法展示
|
下面的代码演示了在Java中使用value_count对price字段进行聚合的逻辑。

网络异常,图片无法展示
|

需要指出的是,如果判断的字段是数组类型,则value_count统计的是符合条件的所有文档中该字段数组中非空元素个数的总和,而不是数组的个数总和。下面的DSL用于统计tags字段数组中非空元素个数的总和。

网络异常,图片无法展示
|

如果需要以空值字段的数据作为聚合指标对其进行聚合,可以在指标统计中通过missing参数指定填充值对空值进行填充。以下示例演示了对price字段进行聚合,并设定了当字段值为空值时使用100进行替代的查询请求。

网络异常,图片无法展示
|
以下代码演示了在Java中当聚合指标为空值时指定填充值的逻辑。

网络异常,图片无法展示
|

3. 桶聚合

前面介绍的聚合指标是指符合条件的文档字段的聚合,有时还需要根据某些维度进行聚合。例如在搜索酒店时,按照城市、是否满房、标签和创建时间等维度统计酒店的平均价格。这些字段统称为“桶”,在同一维度内有一个或者多个桶。例如城市桶,有“北京”“天津”等,是否满房桶,有“满房”“非满房”。

3.1 单维度桶聚合

最简单的桶聚合是单维度桶聚合,指的是按照一个维度对文档进行分组聚合。在桶聚合时,聚合的桶也需要匹配,匹配的方式有terms、filter和ranges等。本节只介绍比较有代表性的terms查询和ranges查询,对其他匹配方式感兴趣读者可以阅读相关文档进行学习,这里不再赘述。

terms聚合是按照字段的实际完整值进行匹配和分组的,它使用的维度字段必须是keyword、bool、keyword数组等适合精确匹配的数据类型,因此不能对text字段直接使用terms聚合,如果对text字段有terms聚合的需求,则需要在创建索引时为该字段增加多字段功能

网络异常,图片无法展示
|

在默认情况下,进行桶聚合时如果不指定指标,则ES默认聚合的是文档计数,该值以doc_count为key存储在每一个bucket子句中。在聚合结果的buckets的两个bucket中,key字段的值分别为“北京”“天津”,表示两个bucket的唯一标识;doccount字段的值分别为3和2,表示两个bucket的文档计数。返回的doccount是近似值,并不是一个准确数,因此在聚合外围,ES给出了两个参考值doc_count_error_upper_bound和sum_other__doc_count,doc_count_error_upper表示被遗漏的文档数量可能存在的最大值,sum_other_doc_count表示除了返回给用户的文档外剩下的文档总数。

网络异常,图片无法展示
|

从上述结果中可以看到,在满房和非满房的bucket结果中多出了一个字段,名称为key_as_string,其值分别是true和false。另外,这两个bucket的key值分别为1和0。这是因为,如果桶字段类型不是keyword类型,ES在聚合时会将桶字段转换为Lucene存储的实际值进行识别。true在Lucene中存储为1,false在Lucene中存储为0,这就是为什么满房和非满房的key字段分别为1和0的原因。 这种情况给用户的使用带来了一些困惑,因为和原始值的差别比较大。针对这个问题,我们可以使用ES提供的key_as_string桶识别字段,它是原始值的字符串形式,和原始值的差别比较小。

以下代码演示了在Java中使用terms聚合进行单维度桶聚合的逻辑:

网络异常,图片无法展示
|

除了terms聚合,ranges聚合也是经常使用的一种聚合。它匹配的是数值字段,表示按照数值范围进行分组。用户可以在ranges中添加分组,每个分组用from和to表示分组的起止数值。注意该分组包含起始数值,不包含终止数值。以下DSL演示了使用ranges进行聚合的方法:

网络异常,图片无法展示
|
以下代码演示了在Java中使用ranges聚合的逻辑:

网络异常,图片无法展示
|

有时还需要对单维度桶指定聚合指标,聚合指标单独使用子aggs进行封装,该aggs子句的使用方式和上一节介绍的聚合指标相同。 以下请求表示按照城市维度进行聚合,统计各个城市的平均酒店价格:

网络异常,图片无法展示
|

在上面的结果中,聚合桶的维度是城市,当前索引中城市为“北京”的文档个数为3,城市为“天津”的文档个数为2。将这两组文档的聚合结果在buckets子句中进行了封装,可以根据key字段进行聚合桶的识别,每个聚合的组中既有文档个数又有价格的加和值。

以下代码演示了在Java中使用桶聚合和指标聚合的逻辑:

网络异常,图片无法展示
|

3.2 多维度桶嵌套聚合

在某些业务需求中,不仅需要一个维度的桶聚合,而且还可能有多维度桶嵌套聚合的需求。例如在搜索酒店时,可能需要统计各个城市的满房和非满房状态下的酒店平均价格ES支持嵌套桶聚合,进行嵌套时,可以使用aggs子句进行子桶的继续嵌套,指标放在最里面的子桶内。以下DSL演示了多维度桶的使用方法:

网络异常,图片无法展示
|
上述DSL被执行后,ES返回的结果如下:

网络异常,图片无法展示
|
从结果中可以看到,第一层的分桶先按照城市分组分为“北京”“天津”;第二层在“北京”“天津”桶下面继续分桶,分为“满房”“非满房”桶,对应的聚合指标即价格的加和值存储在内部的my_sum字段中。

以下代码演示了在Java中使用多维度桶进行聚合的逻辑:

网络异常,图片无法展示
|

3.3 地理距离聚合

按照地理距离进行聚合是一个非常实用的功能,例如在搜索酒店时,可能需要对附近的酒店个数先预览一下 :查看距离当前位置2km范围内、2~3km范围内、5km范围内的酒店个数。 再如,在与电动汽车相关的充电需求中,车主需要搜寻附近充电桩的数量,以便能快速地完成充电。 如图7.3所示为国家电网“e充电”手机App的地图搜索模式,用户附近的汽车充电桩数量将随着地图的缩放而逐渐变化。

网络异常,图片无法展示
|

用户可以使用geo_distance聚合进行地理距离聚合,通过field参数来设置距离计算的字段,可以在origin子句中设定距离的原点,通过unit参数来设置距离的单位,可以选择mi和km,分别表示米和千米。ranges子句用来对距离进行阶段性的分组,该子句的使用方式和前面介绍的range聚合类似。以下DSL演示了使用geo_distance聚合进行地理距离聚合的方法:

网络异常,图片无法展示
|
在上述DSL中,给定了一个地理位置,此处使用ranges聚合对距离该位置的酒店划分了3个分组的桶:第1个桶为3km范围内;第2个桶为3~10km;第3个桶为大于等于10km。执行上述DSL后,ES返回的结果如下:

网络异常,图片无法展示
|
其中,在aggregations结果子句中对应查询的分组有3个bucket桶,表示按照距离划分的3个组,每个bucket桶内分别给出了key和文档数量等信息。

也可以指定聚合指标进行地理距离聚合,下面的DSL将按照bucket分桶聚合酒店的最低价格:

网络异常,图片无法展示
|
执行上述DSL后,聚合结果如下:

网络异常,图片无法展示
|
以下代码演示了在Java中使用地理距离分组并计算最低价格的逻辑: (注意两个聚合之间距离和价格有父子关系)

网络异常,图片无法展示
|



相关实践学习
使用阿里云Elasticsearch体验信息检索加速
通过创建登录阿里云Elasticsearch集群,使用DataWorks将MySQL数据同步至Elasticsearch,体验多条件检索效果,简单展示数据同步和信息检索加速的过程和操作。
ElasticSearch 入门精讲
ElasticSearch是一个开源的、基于Lucene的、分布式、高扩展、高实时的搜索与数据分析引擎。根据DB-Engines的排名显示,Elasticsearch是最受欢迎的企业搜索引擎,其次是Apache Solr(也是基于Lucene)。 ElasticSearch的实现原理主要分为以下几个步骤: 用户将数据提交到Elastic Search 数据库中 通过分词控制器去将对应的语句分词,将其权重和分词结果一并存入数据 当用户搜索数据时候,再根据权重将结果排名、打分 将返回结果呈现给用户 Elasticsearch可以用于搜索各种文档。它提供可扩展的搜索,具有接近实时的搜索,并支持多租户。
相关文章
|
1月前
|
存储 Java API
Elasticsearch 7.8.0从入门到精通
这篇文章详细介绍了Elasticsearch 7.8.0的安装、核心概念(如正排索引和倒排索引)、RESTful风格、各种索引和文档操作、条件查询、聚合查询以及在Spring Boot中整合Elasticsearch的步骤和示例。
112 1
Elasticsearch 7.8.0从入门到精通
|
2月前
|
数据可视化 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
|
2月前
|
存储 关系型数据库 MySQL
浅谈Elasticsearch的入门与实践
本文主要围绕ES核心特性:分布式存储特性和分析检索能力,介绍了概念、原理与实践案例,希望让读者快速理解ES的核心特性与应用场景。
|
3天前
|
存储 SQL 监控
|
2月前
|
存储 自然语言处理 关系型数据库
ElasticSearch基础3——聚合、补全、集群。黑马旅游检索高亮+自定义分词器+自动补全+前后端消息同步
聚合、补全、RabbitMQ消息同步、集群、脑裂问题、集群分布式存储、黑马旅游实现过滤和搜索补全功能
ElasticSearch基础3——聚合、补全、集群。黑马旅游检索高亮+自定义分词器+自动补全+前后端消息同步
|
3月前
|
JSON 搜索推荐 数据挖掘
ElasticSearch的简单介绍与使用【入门篇】
这篇文章是Elasticsearch的入门介绍,涵盖了Elasticsearch的基本概念、特点、安装方法以及如何进行基本的数据操作,包括索引文档、查询、更新、删除和使用bulk API进行批量操作。
ElasticSearch的简单介绍与使用【入门篇】
|
2月前
|
JSON 监控 Java
Elasticsearch 入门:搭建高性能搜索集群
【9月更文第2天】Elasticsearch 是一个分布式的、RESTful 风格的搜索和分析引擎,基于 Apache Lucene 构建。它能够处理大量的数据,提供快速的搜索响应。本教程将指导你如何从零开始搭建一个基本的 Elasticsearch 集群,并演示如何进行简单的索引和查询操作。
192 3
|
3月前
|
JSON 测试技术 API
黑马商城 Elasticsearch从入门到部署 RestClient操作文档
这篇文章详细介绍了如何使用Java的RestHighLevelClient客户端与Elasticsearch进行文档操作,包括新增、查询、删除、修改文档以及批量导入文档的方法,并提供了相应的代码示例和操作步骤。
|
3月前
|
JSON 自然语言处理 Java
Elasticsearch从入门到部署 文档操作 RestAPI
这篇文章详细介绍了Elasticsearch中文档的增删改查操作,并通过Java的RestHighLevelClient客户端演示了如何通过REST API与Elasticsearch进行交云,包括初始化客户端、索引库的创建、删除和存在性判断等操作。
|
3月前
|
JSON 自然语言处理 数据库
Elasticsearch从入门到项目部署 安装 分词器 索引库操作
这篇文章详细介绍了Elasticsearch的基本概念、倒排索引原理、安装部署、IK分词器的使用,以及如何在Elasticsearch中进行索引库的CRUD操作,旨在帮助读者从入门到项目部署全面掌握Elasticsearch的使用。

热门文章

最新文章