将时间戳转换为日期时间以用于 Elasticsearch 聚合
Convert timestamps to datetime for use in Elasticsearch aggregations
我有一个 SendGrid 事件数据的索引:
"_source": {
"externalId": "9283cc1d-b003-xxxx-a5af-84fcf31c4181",
"email": "test@test.com",
"timestamp": 1616515214,
"event": "processed",
"uid": null,
"id": null,
"sendgridEventId": null,
"smtpId": null,
"sgMessageId": null,
"sgEventId": null,
"sendgridEvent": null,
"type": null,
"category": [],
"reason": null,
"status": null,
"url": null,
"useragent": null,
"ip": null,
"response": null,
"tls": null,
"attempt": null,
"sendAt": null,
"asmGroupId": null
}
现在我想使用 timestamp
属性汇总给定日期的所有这些事件。
GET /sendgridevententity/_search
{
"query":
{
"match_all": {}
},
"aggs": {
"amount_per_day": {
"date_histogram": {
"field": "timestamp",
"calendar_interval": "1d"
}
}
}
}
不幸的是,这只会产生所有单个事件,因为它们都有不同的时间戳,并且聚合不会按天对它们进行分组。
如何将时间戳转换为 date
然后 运行 聚合?
你可以利用一个multi field mapping。这是它的工作原理。
- 用新的日期“子字段”更新现有映射。我假设
timestamp
最初被映射为 long
。我还假设时间戳以纪元秒为单位,因此明确设置 format
:
POST sendgridevententity/_mapping
{
"properties": {
"timestamp": {
"type": "long",
"fields": {
"as_date": {
"type": "date",
"format": "epoch_second"
}
}
}
}
}
- 现在需要提取这个新的 属性,您的数据需要 重新索引。您可以通过 cool little trick 触发重建索引调用——发送一个空的
_update_by_query
请求:
POST sendgridevententity/_update_by_query
- 重建索引操作完成后,您可以通过点符号来定位新的日期字段:
GET /sendgridevententity/_search
{
"size": 0,
"query": {
"match_all": {}
},
"aggs": {
"amount_per_day": {
"date_histogram": {
"field": "timestamp.as_date",
"format": "yyyy-MM-dd",
"calendar_interval": "1d"
}
}
}
}
⚠️ 根据您的索引大小和许多其他因素,_update_by_query
请求 可能会出现 超时。可以设置 wait_for_completion=false
来触发异步后台任务。
请注意,我在最终请求中使用了 size: 0
。这是返回 only the aggregation results.
的便捷工具
我有一个 SendGrid 事件数据的索引:
"_source": {
"externalId": "9283cc1d-b003-xxxx-a5af-84fcf31c4181",
"email": "test@test.com",
"timestamp": 1616515214,
"event": "processed",
"uid": null,
"id": null,
"sendgridEventId": null,
"smtpId": null,
"sgMessageId": null,
"sgEventId": null,
"sendgridEvent": null,
"type": null,
"category": [],
"reason": null,
"status": null,
"url": null,
"useragent": null,
"ip": null,
"response": null,
"tls": null,
"attempt": null,
"sendAt": null,
"asmGroupId": null
}
现在我想使用 timestamp
属性汇总给定日期的所有这些事件。
GET /sendgridevententity/_search
{
"query":
{
"match_all": {}
},
"aggs": {
"amount_per_day": {
"date_histogram": {
"field": "timestamp",
"calendar_interval": "1d"
}
}
}
}
不幸的是,这只会产生所有单个事件,因为它们都有不同的时间戳,并且聚合不会按天对它们进行分组。
如何将时间戳转换为 date
然后 运行 聚合?
你可以利用一个multi field mapping。这是它的工作原理。
- 用新的日期“子字段”更新现有映射。我假设
timestamp
最初被映射为long
。我还假设时间戳以纪元秒为单位,因此明确设置format
:
POST sendgridevententity/_mapping
{
"properties": {
"timestamp": {
"type": "long",
"fields": {
"as_date": {
"type": "date",
"format": "epoch_second"
}
}
}
}
}
- 现在需要提取这个新的 属性,您的数据需要 重新索引。您可以通过 cool little trick 触发重建索引调用——发送一个空的
_update_by_query
请求:
POST sendgridevententity/_update_by_query
- 重建索引操作完成后,您可以通过点符号来定位新的日期字段:
GET /sendgridevententity/_search
{
"size": 0,
"query": {
"match_all": {}
},
"aggs": {
"amount_per_day": {
"date_histogram": {
"field": "timestamp.as_date",
"format": "yyyy-MM-dd",
"calendar_interval": "1d"
}
}
}
}
⚠️ 根据您的索引大小和许多其他因素,_update_by_query
请求 可能会出现 超时。可以设置 wait_for_completion=false
来触发异步后台任务。
请注意,我在最终请求中使用了 size: 0
。这是返回 only the aggregation results.