Elasticsearch 在 Date Histogram Aggregation 中使用 pipeline 教程
提示:写完文章后,目录可以自动生成,如何生成可参考右边的帮助文档
前言
最近工作中一直在使用Elasticsearch 的 [agg] 相关操作,一直在做大数据量的统计和报表工作。然后碰到一个比较棘手的问题,就是还在统计过程发现一个年代比久远的索引,其中索引的时间类型是以keyword类型进行录入的,就导致如果通过时间进行聚合的时候就会有很多的ES的高级特性无法使用比如说,笔者一下要将的 Date Histogram Aggregation 日期直方图
,这时候就需要用到ES为我们提供的一个很不错的高级特性,叫做 Script
和 painless
大致需求的样子要做出这样的数据进行
一、painless 是什么?
ElasticStack在升级到5.0版本之后,带来了一个新的脚本语言,painless。
在7.17的最新文档以及给出了解释:
大致意思是:
**Painless是一种简单、安全的脚本语言,专为与 Elasticsearch 一起使用而设计。它是 Elasticsearch 的默认脚本语言,可以安全地用于内联和存储脚本。 **
- 高性能。painless在es的运行速度是其他语言的数倍。
- 安全。使用白名单来限制函数与字段的访问,避免了可能的安全隐患
- 可选类型。你可以在脚本当中使用强类型的编程方式或者动态类型的编程方式。
- 语法。扩展了java的基本语法以兼容groove风格的脚本语言特性,使得plainless易读易写
- 有针对的优化。这门语言是为elasticsearch专门定制的。
二、使用步骤
1.DSL
GET /你的索引名字/_search
{
"aggs": {
"avg_per_day": {
"date_histogram": {
"field": "order_date",
"interval": "day",
"script": {
"source": "return ZonedDateTime.from(ZonedDateTime.of(LocalDateTime.parse(doc['createTime'], DateTimeFormatter.ofPattern('yyyyMMddHHmmss')),ZoneId.systemDefault()).toOffsetDateTime());",
"lang": "painless"
}
}
}
}
}
以下是通过SpringData的RestTemplate进行实现的,HighLevelClient与其类似。如有需要可以效仿,之间少了获取Client的相关代码。
@Resource
private ElasticsearchTemplate elasticsearchTemplate;
// 这里我先构造了一个范围查询,指定一定范围内的数据
RangeQueryBuilder rangeQueryBuilder = QueryBuilders.rangeQuery("createTime")
.gte(startTime)
.lte(endTime);
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder()
.size(0)
.query(rangeQueryBuilder)
.aggregation(//这里的ORDER_DATE_HISTOGRAM 是一个常量字段指定了后续结果字段的名称
AggregationBuilders.dateHistogram(ORDER_DATE_HISTOGRAM)
//这里制定了Interval,表示Date Histogram Aggregation的间隔,因为我们直方图中的间隔是固定的
.dateHistogramInterval(DateHistogramInterval.MONTH)
//这里就是脚本的核心,使用了JAVA代码 进行了时间转换
//笔者的脚本中`createTime`是需要转换的字段,所以这里LocalDateTime.parse的值就是”doc['createTime'].value“,对应了每一个文档中的crarteTime
.script(
new Script(Script.DEFAULT_SCRIPT_TYPE, "painless",
"return ZonedDateTime.from(ZonedDateTime.of("
+ "LocalDateTime.parse(doc['createTime'].value"
+ ".substring(2, 16), DateTimeFormatter.ofPattern('yyyyMMddHHmmss')),"
+ "ZoneId.systemDefault()).toOffsetDateTime());"
, new HashMap<>(2))//这里也可以自定义参数,笔者这里没有自定义参数,所以没有进行赋值,传了一个空Map
)
);
上述代码,因为createDateTime 是KeyWord 的类型,无法使用ES中的”now-6m/m
或者now/m
“的时间函数,所以先进行了rangeQuery 进行了范围锁定,这样可以求出范围内的订单量直方图,就可以使用这种方式来使用ES中的高级特性,然后快速的展示订单的趋势图啦。
总结
以上就是今天要讲的内容,本文仅仅简单介绍了painless 在 Date Histogram Aggregation 中使用的相关小知识。欢迎大家指正。以及painless的使用的其他小技巧。