聚合解决的问题
聚合描述数据的度量、统计以及其他分析结果。它回答:
- 网站平均响应时间
- 基于交易量,谁是最有价值客户
- 在网络传输中,多大的文件才认为是大文件
- 每个产品种类中各有多少产品
ES聚合分类
Elasticsearch将聚合组织为三类:
- Metric 聚合计算度量,例如:字段值的总和、平均数
- Bucket 聚合基于字段值、范围或其他条件,将文档组合到bucket中,也称作bins(箱)
- Pipeline 聚合以其他的聚合作为输入,而不是文档或字段
聚合的运行
在search API中,使用 "aggs" 参数:
GET /my-index-000001/_search
{
"aggs": {
"my-agg-name": {
"terms": {
"field": "my-field"
}
}
}
}
限定聚合的范围
使用 query 参数来信啊顶聚合运行在哪些文档
只返回聚合结果
默认是要返回搜索命中结果,为了只返回聚合结果,需要指定 size 参数为 0
GET /my-index-000001/_search
{
"size": 0,
"aggs": {
"my-agg-name": {
"terms": {
"field": "my-field"
}
}
}
}
运行多个聚合
一个请求中可以包含多个聚合
GET /my-index-000001/_search
{
"aggs": {
"my-first-agg-name": {
"terms": {
"field": "my-field"
}
},
"my-second-agg-name": {
"avg": {
"field": "my-other-field"
}
}
}
}
运行子聚合
bucket 聚合支持 bucket 聚合或 metric 子聚合
GET /my-index-000001/_search
{
"aggs": {
"my-agg-name": {
"terms": {
"field": "my-field"
},
"aggs": {
"my-sub-agg-name": {
"avg": {
"field": "my-other-field"
}
}
}
}
}
}
如上为 term 聚合和 avg 子聚合计算每个 bucket 的文档的平均值。
嵌套子聚合没有级数和深度的限制。
添加指定元数据
使用 meta 对象来关联指定元数据和聚合
GET /my-index-000001/_search
{
"aggs": {
"my-agg-name": {
"terms": {
"field": "my-field"
},
"meta": {
"my-metadata-field": "foo"
}
}
}
}
返回聚合类型
在查询参数上使用 typed_keys 可以让响应消息返回聚合的类型
GET /my-index-000001/_search?typed_keys
{
"aggs": {
"my-agg-name": {
"histogram": {
"field": "my-field",
"interval": 1000
}
}
}
}
返回的类型名作为聚合名的前缀
{
...
"aggregations": {
"histogram#my-agg-name": {
"buckets": []
}
}
}
在聚合中使用脚本
字段可能并不精确匹配聚合,这时你需要聚合的是运行时字段
GET /my-index-000001/_search?size=0
{
"runtime_mappings": {
"message.length": {
"type": "long",
"script": "emit(doc['message.keyword'].value.length())"
}
},
"aggs": {
"message_length": {
"histogram": {
"interval": 10,
"field": "message.length"
}
}
}
}
脚本动态计算字段值,这个给聚合添加了少许开销。
有些聚合,如 terms 和 filters 可以使用为运行时字段做一些优化,总体来说,在性能表现上,使用运行时字段,聚合与聚合之间存在很大差异。
聚合缓存
为了更快的响应,ES 在 shard request cache 缓存频繁运行聚合的结果。要获取缓存结果,每个search 需使用相同的 preference string
如果不需要搜索 hits,设置size 为0 来避免填充缓存
Elasticsearch 给相同的分片用相同的preference string 来路由 searches。如果分片的数据在搜索间不改变,分片将返回缓存的聚合结果
对long 值的限制
在运行聚合时,ES 使用double 值来保存并呈现数字数据,因此,对于long 数字的聚合,超出253的值将取近似值