You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Elasticsearch中int转时间戳取小时及整数转时间戳技术咨询

整数时间戳转日期并提取小时:SQL与Elasticsearch实现方案

一、先解决你SQL里的疑问

你写的SQL其实已经正确实现需求了!咱们拆解下关键部分:

  • FROM_UNIXTIME(create_time):这个函数专门用来把秒级整数时间戳(比如你提到的1600506000)转换成对应的日期时间格式(比如2020-09-19 11:00:00)。MySQL默认处理的就是秒级时间戳,如果你的时间戳是毫秒级的,只需要先除以1000再传入这个函数就行。
  • HOUR(...):从转换后的日期时间里提取小时部分,最后按小时分组求和,完全匹配你的业务需求。

要是想验证的话,可以单独执行SELECT FROM_UNIXTIME(1600506000);,就能看到对应的具体时间,再套上HOUR()就能直接拿到提取的小时数了。

二、Elasticsearch中的实现方法

在Elasticsearch里,分两种场景处理,优先推荐索引阶段的字段映射优化,查询时处理更适合临时需求。

1. 索引阶段:将整数时间戳映射为日期类型(推荐)

如果你的数据还没索引,或者可以重新调整字段映射,直接把create_time定义为date类型,并指定支持秒级时间戳的格式,这样Elasticsearch会自动完成转换,后续查询效率更高:

PUT /your_index
{
  "mappings": {
    "properties": {
      "create_time": {
        "type": "date",
        "format": "epoch_second" // 声明该字段是秒级整数时间戳
      },
      "a": {
        "type": "integer"
      }
    }
  }
}

之后查询时,直接用date_histogram聚合按小时分组,或者用脚本提取小时:

按小时聚合求和的DSL示例:

GET /your_index/_search
{
  "size": 0,
  "aggs": {
    "hourly_count": {
      "date_histogram": {
        "field": "create_time",
        "interval": "hour", // 按小时分组
        "format": "HH" // 返回00-23格式的小时数
      },
      "aggs": {
        "total_count": {
          "sum": {
            "field": "a"
          }
        }
      }
    }
  }
}

2. 查询阶段:临时转换整数时间戳并提取小时

如果无法修改字段映射,只能在查询时用脚本临时处理:

script_fields提取小时(仅查看单条数据的小时结果):

GET /your_index/_search
{
  "script_fields": {
    "hour": {
      "script": {
        "source": "ZonedDateTime.ofInstant(Instant.ofEpochSecond(doc['create_time'].value), ZoneId.of('UTC')).getHour()"
      }
    }
  }
}

按小时聚合求和的DSL示例:

GET /your_index/_search
{
  "size": 0,
  "aggs": {
    "group_by_hour": {
      "terms": {
        "script": {
          "source": "ZonedDateTime.ofInstant(Instant.ofEpochSecond(doc['create_time'].value), ZoneId.of('UTC')).getHour()"
        }
      },
      "aggs": {
        "total_count": {
          "sum": {
            "field": "a"
          }
        }
      }
    }
  }
}

注意:如果你的时间戳是毫秒级的,把Instant.ofEpochSecond改成Instant.ofEpochMilli即可。

内容的提问来源于stack exchange,提问作者wyx

火山引擎 最新活动