将时间戳转换为日期时间以用于 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。这是它的工作原理。

  1. 用新的日期“子字段”更新现有映射。我假设 timestamp 最初被映射为 long。我还假设时间戳以纪元秒为单位,因此明确设置 format:
POST sendgridevententity/_mapping
{
  "properties": {
    "timestamp": {
      "type": "long",
      "fields": {
        "as_date": {
          "type": "date",
          "format": "epoch_second"
        }
      }
    }
  }
}
  1. 现在需要提取这个新的 属性,您的数据需要 重新索引。您可以通过 cool little trick 触发重建索引调用——发送一个空的 _update_by_query 请求:
POST sendgridevententity/_update_by_query
  1. 重建索引操作完成后,您可以通过点符号来定位新的日期字段:
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.

的便捷工具