在弹性搜索 date_histogram 聚合中将长时间戳表示为日期
Representing a long timestamp as date in elastic search date_histogram aggregation
我有一个索引,其中 ts
字段代表纪元 ms:
"ts": {
"type": "long"
}
注意类型是 long
,不是 epoch_millis
日期类型。
I 运行 该字段上的日期直方图聚合:
{
...
"aggs": {
"agg_name": {
"date_histogram": {
"field": "ts",
"interval": "1d",
"format": "yyyy-MM-dd",
"min_doc_count": 1
}
}
}
}
正在尝试以每天的文档为基础进行汇总。
操作运行没问题,但是一个bucket输出如下:
{
"key_as_string": "yyyy-MM-dd1577836800000",
"key": 1577836800000,
"doc_count": 3
}
我的问题是:如何在不更改字段类型的情况下将 key_as_string
呈现为 2020-01-01
之类的东西。
您可以使用 painless scripting language 来实现您想要的,但效率不高,因为无痛脚本在字段操作方面有很多开销。这是执行此操作的脚本方法
您可以设置格式并将纪元的长整数转换为纪元的瞬时值,然后按照您想要的方式进行格式化。如前所述,这效率不高,但可以完成工作。
{
"aggs": {
"dt_terms": {
"terms": {
"script": {
"source": """
DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyy-MM-dd").withZone(ZoneId.systemDefault());
return df.format(Instant.ofEpochMilli(doc['ts'].value));
""",
"lang": "painless"
}
}
}
}
}
由于您不想修改原始字段的数据类型,另一种实现方式是使用 copy_to 字段。在您的映射中,如果您添加如下所示的新 copy_to 字段并使用日期数据类型,则您不必 运行 脚本并使用其复制到的字段进行聚合。
PUT /index_name/_mapping
{
"properties": {
"ts": {
"type": "long",
"copy_to": "ts_d"
},
"ts_d": {
"type": "date"
}
}
}
如果你有上面的映射,你可以使用 reindex API 来索引新的映射,然后使用下面的查询,它现在可以处理日期数据类型。
GET /_search
{
"aggs": {
"agg_name": {
"date_histogram": {
"field": "ts_d",
"interval": "1d",
"format": "yyyy-MM-dd",
"min_doc_count": 1
}
}
}
}
我有一个索引,其中 ts
字段代表纪元 ms:
"ts": {
"type": "long"
}
注意类型是 long
,不是 epoch_millis
日期类型。
I 运行 该字段上的日期直方图聚合:
{
...
"aggs": {
"agg_name": {
"date_histogram": {
"field": "ts",
"interval": "1d",
"format": "yyyy-MM-dd",
"min_doc_count": 1
}
}
}
}
正在尝试以每天的文档为基础进行汇总。 操作运行没问题,但是一个bucket输出如下:
{
"key_as_string": "yyyy-MM-dd1577836800000",
"key": 1577836800000,
"doc_count": 3
}
我的问题是:如何在不更改字段类型的情况下将 key_as_string
呈现为 2020-01-01
之类的东西。
您可以使用 painless scripting language 来实现您想要的,但效率不高,因为无痛脚本在字段操作方面有很多开销。这是执行此操作的脚本方法
您可以设置格式并将纪元的长整数转换为纪元的瞬时值,然后按照您想要的方式进行格式化。如前所述,这效率不高,但可以完成工作。
{
"aggs": {
"dt_terms": {
"terms": {
"script": {
"source": """
DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyy-MM-dd").withZone(ZoneId.systemDefault());
return df.format(Instant.ofEpochMilli(doc['ts'].value));
""",
"lang": "painless"
}
}
}
}
}
由于您不想修改原始字段的数据类型,另一种实现方式是使用 copy_to 字段。在您的映射中,如果您添加如下所示的新 copy_to 字段并使用日期数据类型,则您不必 运行 脚本并使用其复制到的字段进行聚合。
PUT /index_name/_mapping
{
"properties": {
"ts": {
"type": "long",
"copy_to": "ts_d"
},
"ts_d": {
"type": "date"
}
}
}
如果你有上面的映射,你可以使用 reindex API 来索引新的映射,然后使用下面的查询,它现在可以处理日期数据类型。
GET /_search
{
"aggs": {
"agg_name": {
"date_histogram": {
"field": "ts_d",
"interval": "1d",
"format": "yyyy-MM-dd",
"min_doc_count": 1
}
}
}
}