030 ElasticSearch----全文检索技术05---基础知识详解03-聚合
聚合可以让我们极其方便的实现对数据的统计、分析。例如:
什么品牌的手机最受欢迎?
这些手机的平均价格、最高价格、最低价格?
这些手机每月的销售情况如何?
实现这些统计功能的比数据库的sql要方便的多,而且查询速度非常快,可以实现实时搜索效果。
1.基本概念
Elasticsearch中的聚合,包含多种类型,最常用的两种,一个叫桶,一个叫度量:
(1)桶
桶的作用,是按照某种方式对数据进行分组,每一组数据在ES中称为一个桶,例如我们根据国籍对人划分,可以得到中国桶、英国桶,日本桶……或者我们按照年龄段对人进行划分:0~10,10~20,20~30,30~40等。
Elasticsearch中提供的划分桶的方式有很多:
Date Histogram Aggregation:根据日期阶梯分组,例如给定阶梯为周,会自动每周分为一组
Histogram Aggregation:根据数值阶梯分组,与日期类似
Terms Aggregation:根据词条内容分组,词条内容完全匹配的为一组
Range Aggregation:数值和日期的范围分组,指定开始和结束,然后按段分组
……
bucket aggregations 只负责对数据进行分组,并不进行计算,因此往往bucket中往往会嵌套另一种聚合:metrics aggregations即度量
(2)度量(metrics)
分组完成以后,我们一般会对组中的数据进行聚合运算,例如求平均值、最大、最小、求和等,这些在ES中称为度量
比较常用的一些度量聚合方式:
Avg Aggregation:求平均值
Max Aggregation:求最大值
Min Aggregation:求最小值
Percentiles Aggregation:求百分比
Stats Aggregation:同时返回avg、max、min、sum、count等
Sum Aggregation:求和
Top hits Aggregation:求前几
Value Count Aggregation:求总数
……
为了测试聚合,我们先批量导入一些数据
创建索引及映射:
PUT /cars
{
"settings": {
"number_of_shards": 1,
"number_of_replicas": 0
},
"mappings": {
"transactions": {
"properties": {
"color": {
"type": "keyword"
},
"make": {
"type": "keyword"
}
}
}
}
}
利用postman工具:

响应结果:

使用 Elasticsearch Bulk API /_bulk批量导入数据
POST /cars/transactions/_bulk
{ "index": {}}
{ "price" : 10000, "color" : "red", "make" : "honda", "sold" : "2014-10-28" }
{ "index": {}}
{ "price" : 20000, "color" : "red", "make" : "honda", "sold" : "2014-11-05" }
{ "index": {}}
{ "price" : 30000, "color" : "green", "make" : "ford", "sold" : "2014-05-18" }
{ "index": {}}
{ "price" : 15000, "color" : "blue", "make" : "toyota", "sold" : "2014-07-02" }
{ "index": {}}
{ "price" : 12000, "color" : "green", "make" : "toyota", "sold" : "2014-08-19" }
{ "index": {}}
{ "price" : 20000, "color" : "red", "make" : "honda", "sold" : "2014-11-05" }
{ "index": {}}
{ "price" : 80000, "color" : "red", "make" : "bmw", "sold" : "2014-01-01" }
{ "index": {}}
{ "price" : 25000, "color" : "blue", "make" : "ford", "sold" : "2014-02-12" }
注意:必须有换行符。

响应结果:

注意:在ES中,需要进行聚合、排序、过滤的字段其处理方式比较特殊,因此不能被分词。这里我们将color和make这两个文字类型的字段设置为keyword类型,这个类型不会被分词,将来就可以参与聚合
2.聚合为桶
首先,我们按照 汽车的颜色color来划分桶
GET /cars/_search
{
"size" : 0,
"aggs" : {
"popular_colors" : {
"terms" : {
"field" : "color"
}
}
}
}
size: 查询条数,这里设置为0,因为我们不关心搜索到的数据,只关心聚合结果,提高效率
aggs:声明这是一个聚合查询,是aggregations的缩写
popular_colors:给这次聚合起一个名字,任意。
terms:划分桶的方式,这里是根据词条划分
field:划分桶的字段

响应结果:

hits:查询结果为空,因为我们设置了size为0
aggregations:聚合的结果
popular_colors:我们定义的聚合名称
buckets:查找到的桶,每个不同的color字段值都会形成一个桶
key:这个桶对应的color字段的值
doc_count:这个桶中的文档数量
通过聚合的结果我们发现,目前红色的小车比较畅销!
3.桶内度量
前面的例子告诉我们每个桶里面的文档数量,这很有用。 但通常,我们的应用需要提供更复杂的文档度量。 例如,每种颜色汽车的平均价格是多少?
因此,我们需要告诉Elasticsearch使用哪个字段,使用何种度量方式进行运算,这些信息要嵌套在桶内,度量的运算会基于桶内的文档进行
现在,我们为刚刚的聚合结果添加 求价格平均值的度量:
GET /cars/_search
{
"size" : 0,
"aggs" : {
"popular_colors" : {
"terms" : {
"field" : "color"
},
"aggs":{
"avg_price": {
"avg": {
"field": "price"
}
}
}
}
}
}
postman工具使用:

aggs:我们在上一个aggs(popular_colors)中添加新的aggs。可见
度量也是一个聚合avg_price:聚合的名称
avg:度量的类型,这里是求平均值
field:度量运算的字段
响应结果:

4.桶内嵌套桶
刚刚的案例中,我们在桶内嵌套度量运算。事实上桶不仅可以嵌套运算, 还可以再嵌套其它桶。也就是说在每个分组中,再分更多组。
比如:我们想统计每种颜色的汽车中,分别属于哪个制造商,按照make字段再进行分桶
GET /cars/_search
{
"size" : 0,
"aggs" : {
"popular_colors" : {
"terms" : {
"field" : "color"
},
"aggs":{
"avg_price": {
"avg": {
"field": "price"
}
},
"maker":{
"terms":{
"field":"make"
}
}
}
}
}
}
原来的color桶和avg计算我们不变
maker:在嵌套的aggs下新添一个桶,叫做maker
terms:桶的划分类型依然是词条
filed:这里根据make字段进行划分
postman中响应结果:
{
"took": 16,
"timed_out": false,
"_shards": {
"total": 1,
"successful": 1,
"skipped": 0,
"failed": 0
},
"hits": {
"total": 8,
"max_score": 0.0,
"hits": []
},
"aggregations": {
"popular_colors": {
"doc_count_error_upper_bound": 0,
"sum_other_doc_count": 0,
"buckets": [
{
"key": "red",
"doc_count": 4,
"maker": {
"doc_count_error_upper_bound": 0,
"sum_other_doc_count": 0,
"buckets": [
{
"key": "honda",
"doc_count": 3
},
{
"key": "bmw",
"doc_count": 1
}
]
},
"avg_price": {
"value": 32500.0
}
},
{
"key": "blue",
"doc_count": 2,
"maker": {
"doc_count_error_upper_bound": 0,
"sum_other_doc_count": 0,
"buckets": [
{
"key": "ford",
"doc_count": 1
},
{
"key": "toyota",
"doc_count": 1
}
]
},
"avg_price": {
"value": 20000.0
}
},
{
"key": "green",
"doc_count": 2,
"maker": {
"doc_count_error_upper_bound": 0,
"sum_other_doc_count": 0,
"buckets": [
{
"key": "ford",
"doc_count": 1
},
{
"key": "toyota",
"doc_count": 1
}
]
},
"avg_price": {
"value": 21000.0
}
}
]
}
}
}
我们可以看到,新的聚合
maker被嵌套在原来每一个color的桶中。每个颜色下面都根据
make字段进行了分组我们能读取到的信息:
红色车共有4辆
红色车的平均售价是 $32,500 美元。
其中3辆是 Honda 本田制造,1辆是 BMW 宝马制造。
030 ElasticSearch----全文检索技术05---基础知识详解03-聚合的更多相关文章
- Cisco路由技术基础知识详解
第一部分 请写出568A的线序(接触网络第一天就应该会的,只要你掐过,想都能想出来) .网卡MAC地址长度是( )个二进制位(16进制与2进制的换算关系,只是换种方式问,不用你拿笔去算) A.12 ...
- RabbitMQ,Apache的ActiveMQ,阿里RocketMQ,Kafka,ZeroMQ,MetaMQ,Redis也可实现消息队列,RabbitMQ的应用场景以及基本原理介绍,RabbitMQ基础知识详解,RabbitMQ布曙
消息队列及常见消息队列介绍 2017-10-10 09:35操作系统/客户端/人脸识别 一.消息队列(MQ)概述 消息队列(Message Queue),是分布式系统中重要的组件,其通用的使用场景可以 ...
- RabbitMQ基础知识详解
什么是MQ? MQ全称为Message Queue, 消息队列(MQ)是一种应用程序对应用程序的通信方法.MQ是消费-生产者模型的一个典型的代表,一端往消息队列中不断写入消息,而另一端则可以读取队列中 ...
- Python基础知识详解 从入门到精通(七)类与对象
本篇主要是介绍python,内容可先看目录其他基础知识详解,欢迎查看本人的其他文章Python基础知识详解 从入门到精通(一)介绍Python基础知识详解 从入门到精通(二)基础Python基础知识详 ...
- 直播一:H.264编码基础知识详解
一.编码基础概念 1.为什么要进行视频编码? 视频是由一帧帧图像组成,就如常见的gif图片,如果打开一张gif图片,可以发现里面是由很多张图片组成.一般视频为了不让观众感觉到卡顿,一秒钟至少需要16帧 ...
- 第157天:canvas基础知识详解
目录 一.canvas简介 1.1 什么是canvas?(了解) 1.2 canvas主要应用的领域(了解) 二.canvas绘图基础 2.0 sublime配置canvas插件(推荐) 2.1 Ca ...
- redis基础知识详解
一.redis基础知识 1.Redis是什么Redis是一个开源的key-value存储系统. 和Memcached类似,它支持存储的value类型相对更多,包括string(字符串).list(链表 ...
- 【干货】用大白话聊聊JavaSE — ArrayList 深入剖析和Java基础知识详解(二)
在上一节中,我们简单阐述了Java的一些基础知识,比如多态,接口的实现等. 然后,演示了ArrayList的几个基本方法. ArrayList是一个集合框架,它的底层其实就是一个数组,这一点,官方文档 ...
- Thrift入门初探(2)--thrift基础知识详解
昨天总结了thrift的安装和入门实例,Thrift入门初探--thrift安装及java入门实例,今天开始总结一下thrift的相关基础知识. Thrift使用一种中间语言IDL,来进行接口的定义, ...
- Java网络编程一:基础知识详解
网络基础知识 1.OSI分层模型和TCP/IP分层模型的对应关系 这里对于7层模型不展开来讲,只选择跟这次系列主题相关的知识点介绍. 2.七层模型与协议的对应关系 网络层 ------------ ...
随机推荐
- codeforces #577(Div.2)
codeforces #577(Div.2) A Important Exam A class of students wrote a multiple-choice test. There are ...
- ES6 Set和Map集合(六)
一.Set集合创建Set实例:let set = new Set();1.特性:a.Set本身是一个构造函数,用来生成Set数据结构[类比数组结构]b.Set函数可以接受具有Iterable接口的数据 ...
- JVM性能优化简介
01. JVM是什么 概述: 大白话: 全称Java Virtual Machine(Java虚拟机), 它是一个虚构出来的计算机, 通过实际的计算机来模拟 ...
- springboot工程启动即执行一段代码
最近在做一个项目, 需要Tomcat启动后就执行一段代码 在这里需要用到CommandLineRunner这个接口, Spring boot的CommandLineRunner接口主要用于实现在应用初 ...
- php获取ssl验证的https页面的源码
$response = "https://faculty.xidian.edu.cn/system/resource/tsites/tsitesencrypt.jsp?id=_tsites_ ...
- PCA 在手写数字数据集上的应用
在 skilearn 的手写数据集中,每个数据点都是 0 到 9 之间手写数字的一张 8*8 灰度图像.用 PCA 将其降维到二维,并可视化数据点,如下: 1.digits 数据演示: from sk ...
- LCD编程_画点线圆
上篇博客中进行了lcd的简单测试,这篇博客将进行更加复杂的测试——画点.画线.画圆.画线和画圆是在画点的基础上实现的,因此本篇博客重点实现画点操作. 先抛出这样的一个问题,已知: (x,y)的坐标: ...
- 水晶报表 VS2010 应用
VS.NET2010水晶报表安装部署[VS2010] 欢迎C#高手加盟QQ群:9340166 水晶报表VS2010版IDE安装标准版SAP Crystal Reports, version for ...
- 2.搭建第一个http服务:三层架构
package main import ( "github.com/go-kit/kit/transport/http" "gomicro/Services" ...
- yii2 Query Builder 查询打印sql语句
$query = new Query(); $query->select('gs.*, g.goods_images, sa.attr_name, sa.is_default, sa.alias ...