【问题标题】:Convert timestamps to datetime for use in Elasticsearch aggregations将时间戳转换为日期时间以用于 Elasticsearch 聚合
【发布时间】:2021-03-26 12:47:02
【问题描述】:

我有一个 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,然后运行聚合?

【问题讨论】:

    标签: elasticsearch elasticsearch-aggregation elasticsearch-date


    【解决方案1】:

    您可以利用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的便捷工具。

    【讨论】:

    • 另外一个问题:我喜欢在 Kibana 可视化中使用它。但是对于 Bucket,我不能使用该格式,它只是声明没有“日期”类型的字段。有没有办法在那里也使用这个字段?
    • 是的,应该是。可能需要重新创建Index Pattern,以便它也可以获取日期字段。顺便说一句,它不是date——它是timestamp.as_date,当索引模式是最新的时,应该能够从下拉列表中进行选择。
    猜你喜欢
    • 1970-01-01
    • 2017-04-25
    • 2022-01-08
    • 1970-01-01
    • 2020-10-19
    • 2016-11-26
    相关资源
    最近更新 更多