发现问题

  1. 创建索引,配置date类型字段
  2. 批量插入数据,格式分别为带时区信息,不带时区信息,时间戳
  3. 对数据进行聚合
  4. 对数据进行查询,分别使用带时区信息,不带时区信息,时间戳三种格式

创建索引,配置字段类型

PUT testdate
{"mappings": {"testdate":{"properties": {"tag":{"type": "keyword"},"datetime":{"type": "date"}}}}
}

批量插入数据

POST /_bulk
{"create":{"_index":"testdate","_type":"testdate","_id":1}}
{"tag":"带时区信息","datetime":"2019-07-15T08:00:00+08:00"}
{"create":{"_index":"testdate","_type":"testdate","_id":2}}
{"tag":"不带时区信息","datetime":"2019-07-15T08:00:00"}
{"create":{"_index":"testdate","_type":"testdate","_id":3}}
{"tag":"时间戳","datetime":"1563148800000"}

对数据进行聚合操作
不带时区信息聚合

POST /testdate/testdate/_search
{"size": 0, "aggs": {"aggs_datetime": {"date_histogram": {"field": "datetime","interval": "hour"},"aggs": {"aggs_tag": {"terms": {"field": "tag","size": 10}}}}}
}

结果
不带时区信息时间显示正常, 时间戳和带时区信息时间提前8小时

{"took": 2,"timed_out": false,"_shards": {"total": 5,"successful": 5,"skipped": 0,"failed": 0},"hits": {"total": 3,"max_score": 0,"hits": []},"aggregations": {"aggs_datetime": {"buckets": [{"key_as_string": "2019-07-15T00:00:00.000Z","key": 1563148800000,"doc_count": 2,"aggs_tag": {"doc_count_error_upper_bound": 0,"sum_other_doc_count": 0,"buckets": [{"key": "带时区信息","doc_count": 1},{"key": "时间戳","doc_count": 1}]}},{"key_as_string": "2019-07-15T01:00:00.000Z","key": 1563152400000,"doc_count": 0,"aggs_tag": {"doc_count_error_upper_bound": 0,"sum_other_doc_count": 0,"buckets": []}},{"key_as_string": "2019-07-15T02:00:00.000Z","key": 1563156000000,"doc_count": 0,"aggs_tag": {"doc_count_error_upper_bound": 0,"sum_other_doc_count": 0,"buckets": []}},{"key_as_string": "2019-07-15T03:00:00.000Z","key": 1563159600000,"doc_count": 0,"aggs_tag": {"doc_count_error_upper_bound": 0,"sum_other_doc_count": 0,"buckets": []}},{"key_as_string": "2019-07-15T04:00:00.000Z","key": 1563163200000,"doc_count": 0,"aggs_tag": {"doc_count_error_upper_bound": 0,"sum_other_doc_count": 0,"buckets": []}},{"key_as_string": "2019-07-15T05:00:00.000Z","key": 1563166800000,"doc_count": 0,"aggs_tag": {"doc_count_error_upper_bound": 0,"sum_other_doc_count": 0,"buckets": []}},{"key_as_string": "2019-07-15T06:00:00.000Z","key": 1563170400000,"doc_count": 0,"aggs_tag": {"doc_count_error_upper_bound": 0,"sum_other_doc_count": 0,"buckets": []}},{"key_as_string": "2019-07-15T07:00:00.000Z","key": 1563174000000,"doc_count": 0,"aggs_tag": {"doc_count_error_upper_bound": 0,"sum_other_doc_count": 0,"buckets": []}},{"key_as_string": "2019-07-15T08:00:00.000Z","key": 1563177600000,"doc_count": 1,"aggs_tag": {"doc_count_error_upper_bound": 0,"sum_other_doc_count": 0,"buckets": [{"key": "不带时区信息","doc_count": 1}]}}]}}
}

东八区

POST /testdate/testdate/_search
{"size": 0, "aggs": {"aggs_datetime": {"date_histogram": {"field": "datetime","interval": "hour","time_zone": "+08:00"},"aggs": {"aggs_tag": {"terms": {"field": "tag","size": 10}}}}}
}

结果
时间戳和带时区信息时间显示正常, 不带时区信息时间推后8小时

{"took": 3,"timed_out": false,"_shards": {"total": 5,"successful": 5,"skipped": 0,"failed": 0},"hits": {"total": 3,"max_score": 0,"hits": []},"aggregations": {"aggs_datetime": {"buckets": [{"key_as_string": "2019-07-15T08:00:00.000+08:00","key": 1563148800000,"doc_count": 2,"aggs_tag": {"doc_count_error_upper_bound": 0,"sum_other_doc_count": 0,"buckets": [{"key": "带时区信息","doc_count": 1},{"key": "时间戳","doc_count": 1}]}},{"key_as_string": "2019-07-15T09:00:00.000+08:00","key": 1563152400000,"doc_count": 0,"aggs_tag": {"doc_count_error_upper_bound": 0,"sum_other_doc_count": 0,"buckets": []}},{"key_as_string": "2019-07-15T10:00:00.000+08:00","key": 1563156000000,"doc_count": 0,"aggs_tag": {"doc_count_error_upper_bound": 0,"sum_other_doc_count": 0,"buckets": []}},{"key_as_string": "2019-07-15T11:00:00.000+08:00","key": 1563159600000,"doc_count": 0,"aggs_tag": {"doc_count_error_upper_bound": 0,"sum_other_doc_count": 0,"buckets": []}},{"key_as_string": "2019-07-15T12:00:00.000+08:00","key": 1563163200000,"doc_count": 0,"aggs_tag": {"doc_count_error_upper_bound": 0,"sum_other_doc_count": 0,"buckets": []}},{"key_as_string": "2019-07-15T13:00:00.000+08:00","key": 1563166800000,"doc_count": 0,"aggs_tag": {"doc_count_error_upper_bound": 0,"sum_other_doc_count": 0,"buckets": []}},{"key_as_string": "2019-07-15T14:00:00.000+08:00","key": 1563170400000,"doc_count": 0,"aggs_tag": {"doc_count_error_upper_bound": 0,"sum_other_doc_count": 0,"buckets": []}},{"key_as_string": "2019-07-15T15:00:00.000+08:00","key": 1563174000000,"doc_count": 0,"aggs_tag": {"doc_count_error_upper_bound": 0,"sum_other_doc_count": 0,"buckets": []}},{"key_as_string": "2019-07-15T16:00:00.000+08:00","key": 1563177600000,"doc_count": 1,"aggs_tag": {"doc_count_error_upper_bound": 0,"sum_other_doc_count": 0,"buckets": [{"key": "不带时区信息","doc_count": 1}]}}]}}
}

对数据进行结构化查询
时间戳

POST /testdate/testdate/_search
{"query": {"range": {"datetime": {"gte": 1563148800000}}}
}

三条数据全部返回

{"took": 2,"timed_out": false,"_shards": {"total": 5,"successful": 5,"skipped": 0,"failed": 0},"hits": {"total": 3,"max_score": 1,"hits": [{"_index": "testdate","_type": "testdate","_id": "2","_score": 1,"_source": {"tag": "不带时区信息","datetime": "2019-07-15T08:00:00"}},{"_index": "testdate","_type": "testdate","_id": "1","_score": 1,"_source": {"tag": "带时区信息","datetime": "2019-07-15T08:00:00+08:00"}},{"_index": "testdate","_type": "testdate","_id": "3","_score": 1,"_source": {"tag": "时间戳","datetime": "1563148800000"}}]}
}

不带时区

POST /testdate/testdate/_search
{"query": {"range": {"datetime": {"gte": "2019-07-15T08:00:00"}}}
}

只返回了不带时区信息的一条数据

{"took": 1,"timed_out": false,"_shards": {"total": 5,"successful": 5,"skipped": 0,"failed": 0},"hits": {"total": 1,"max_score": 1,"hits": [{"_index": "testdate","_type": "testdate","_id": "2","_score": 1,"_source": {"tag": "不带时区信息","datetime": "2019-07-15T08:00:00"}}]}
}

带时区

POST /testdate/testdate/_search
{"query": {"range": {"datetime": {"gte": "2019-07-15T08:00:00+08:00"}}}
}

三条数据全部返回

{"took": 0,"timed_out": false,"_shards": {"total": 5,"successful": 5,"skipped": 0,"failed": 0},"hits": {"total": 3,"max_score": 1,"hits": [{"_index": "testdate","_type": "testdate","_id": "2","_score": 1,"_source": {"tag": "不带时区信息","datetime": "2019-07-15T08:00:00"}},{"_index": "testdate","_type": "testdate","_id": "1","_score": 1,"_source": {"tag": "带时区信息","datetime": "2019-07-15T08:00:00+08:00"}},{"_index": "testdate","_type": "testdate","_id": "3","_score": 1,"_source": {"tag": "时间戳","datetime": "1563148800000"}}]}
}

原因分析

    /*** @desc : 时间戳* @author : cheng* @date : 2019-12-10 23:23*/@Testpublic void testA() throws Exception{String dateStr = "2019-07-15 08:00:00";SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");// 解析字符串,时区:东八区Date date = dateFormat.parse(dateStr);System.out.println(date.getTime());// 格式化日期,时区:0时区dateFormat.setTimeZone(TimeZone.getTimeZone("GMT"));System.out.println(dateFormat.format(date));}// 输出15631488000002019-07-15 00:00:00
    /*** @desc : 带时区* @author : cheng* @date : 2019-12-10 23:24*/@Testpublic void testB() throws Exception{String dateStr = "2019-07-15 08:00:00+0800";SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ssZ");// 解析字符串,时区:东八区Date date = dateFormat.parse(dateStr);// 格式化日期,时区:0时区dateFormat.setTimeZone(TimeZone.getTimeZone("GMT"));System.out.println(dateFormat.format(date));}// 输出2019-07-15 00:00:00+0000
    /*** @desc : 不带时区信息* @author : cheng* @date : 2019-12-10 23:23*/@Testpublic void testC() throws Exception{String dateStr = "2019-07-15 08:00:00";SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");// 解析字符串,时区:0时区dateFormat.setTimeZone(TimeZone.getTimeZone("GMT"));Date date = dateFormat.parse(dateStr);// 格式化日期,时区:0时区dateFormat.setTimeZone(TimeZone.getTimeZone("GMT"));System.out.println(dateFormat.format(date));}// 输出2019-07-15 08:00:00

ES日期类型使用UTC

时间戳1563148800000
时间戳本身就是UTC毫秒数, 和时区没有关系, 实际存储的就是这个值

String dateStr = "2019-07-15 08:00:00";
// 时间戳和时区无关, UTC毫秒数
System.out.println(DateUtils.parseDate(dateStr, Locale.ENGLISH, "yyyy-MM-dd HH:mm:ss").getTime());
System.out.println(DateUtils.parseDate(dateStr, Locale.US, "yyyy-MM-dd HH:mm:ss").getTime());
System.out.println(DateUtils.parseDate(dateStr, Locale.FRENCH, "yyyy-MM-dd HH:mm:ss").getTime());输出
1563148800000
1563148800000
1563148800000

不带时区信息格式2019-07-15T08:00:00
等价于2019-07-15T08:00:00+00:00, 默认就是UTC 0时区时间, 实际存储的就是这个值

带时区信息格式2019-07-15T08:00:00+08:00
东八区时间 = UTC0时区 + 8个小时
所以实际存储的值为UTC0时区 = 东八区 - 8小时 = 2019-07-15T00:00:00+00:00, 实际存储2019-07-15T00:00:00+00:00

// 本地时间为2019-07-15 08:00:00
Date date = new Date();
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");// 不设置时区, 默认为机器所在时区
System.out.println(sdf.format(date));// 东八区
sdf.setTimeZone(TimeZone.getTimeZone("GMT+8"));
System.out.println(sdf.format(date));// 0时区 = 东八区 - 8个小时
sdf.setTimeZone(TimeZone.getTimeZone("GMT"));
System.out.println(sdf.format(date));输出
2019-07-15 08:00:00
2019-07-15 08:00:00
2019-07-15 00:00:00

总结

  • 存储:es使用UTC时间存储date类型
  • 查询:查询的时间会转换成UTC时间,然后进行查询操作

使用建议

  • 强制:存入es的日期类型数据,必须全部带上时区信息或者使用时间戳(可视化效果差,不建议)
  • 强制:使用日期聚合时,必须带上时区信息
  • 强制:查询日期类型数据是,必须带上时区信息,或者时间戳(可视化效果差,不建议)

索引中的文档存在跨时区,那么索引,聚合,查询时都需要带上时区信息
索引中的文档不存在跨时区,即全在同一时区,那么索引,聚合,查询时都不需要带上时区信息

Elasticsearch时区问题相关推荐

  1. Elasticsearch 滞后8个小时等时区问题,一网打尽!

    1.实战问题 如下都是实战环节遇到的问题: logstash谁解决过时区问题,mysql是东八区shanghai 但是这玩意读完存到es就少了8小时? 目前索引会比真正时间晚8小时,导致8点前的日志写 ...

  2. Elasticsearch中的date与时区问题

    1 前言 本文主要讲解Elasticsearch中date类型数据的底层存储原理,以及对带时区日期字符串和不带时区的日期字符串如何在ES底层存储进行验证.对于直接存储Long类型时间戳,不作过多描述. ...

  3. Elasticsearch查询相关总结以及timestamp和时区问题

    ES查询相关 参考:https://www.cnblogs.com/qdhxhz/p/11493677.html 如果想筛选出特定时间段的event,可以在查询语句里使用post_filter POS ...

  4. java反序列化时区,Jackson使用Java 8将Elasticsearch反序列化为LocalDateTime

    我们在日期字段中填充了longinlasticsearch索引. 字段映射为: @Field(type = FieldType.Date) @JsonFormat(shape = JsonFormat ...

  5. elasticsearch docker无法挂载_使用Docker安装Graylog日志收集系统

    1.创建并进入到用于存放Graylog配置文件的目录 mkdir -p /data/graylog/config && cd /data/graylog/config 2.下载Gray ...

  6. 平滑无损!引入Elasticsearch的系统架构实战

    [文章来源]https://sourl.cn/L6WUGC 前 言 我曾经面试安踏的技术岗,当时面试官问了我一个问题:如果你想使用某个新技术但是领导不愿意,你怎么办? 对于该问题我相信大家就算没有面试 ...

  7. elasticsearch数据长期保存的方案

    Elasticsearch的数据就存储在硬盘中.当我们的访问日志非常大时,kabana绘制图形的时候会非常缓慢.而且硬盘空间有限,不可能保存所有的日志文件.如果我们想获取站点每天的重要数据信息,比如每 ...

  8. ElasticSearch大数据分布式弹性搜索引擎使用

    阅读目录: 背景 安装 查找.下载rpm包 .执行rpm包安装 配置elasticsearch专属账户和组 设置elasticsearch文件所有者 切换到elasticsearch专属账户测试能否成 ...

  9. 使用docker搭建一个elasticsearch(5.4)的基础环境

    2019独角兽企业重金招聘Python工程师标准>>> docker is a cool technology! 这篇文章主要讲解的是搭建一个es的基本环境(默认docker环境已经 ...

最新文章

  1. CentOS 5.5 编译安装apache+php+mysql,利用CMS快速建立论坛
  2. win10镜像重装,快速设置之后无限重启怎么办?
  3. 《深入理解java虚拟机》
  4. 解决Layui的switch样式显示问题
  5. OSChina 周三乱弹 —— 孤独到都和病毒发生了感情了
  6. 【opencv系列06】OpenCV4.X滑动条操作
  7. 【Tiny4412】 Android系统的烧写
  8. Netty初步之hello world
  9. 零云九歌小组KTV点歌系统简介
  10. PCM复用设备和PDH设备的区别介绍
  11. 解决linux下QtCreator无法输入中文的情况
  12. python的回收机制_Python的垃圾回收机制深入分析
  13. bootstrap 3.0 LESS源代码浅析(一)
  14. 一、Java多线程基础
  15. 新基建 X 巡检机器人:AI赋能,从“前锋”到“统帅”
  16. C++11创建线程的三种方式
  17. [Python]更改图片底色
  18. ERP常用模块顾问行情对比
  19. 计算机卷死,一位计算机教师死了,警方在床底发现一张纸,上面写着一些特殊的符号,这... #119615-推理漫画-侦探推理-33IQ...
  20. 每周一看:16份文档资料,程序员软硬实力全概览,总有一个适合你

热门文章

  1. 两台电脑通过trunk口互通,修改trunk 接口pvid后不通了 <1>
  2. JPO 创建Excel相关问题解决
  3. 岁月蹉跎,人生几何。
  4. office2017官方正版
  5. 比较好的开源商城系统
  6. canvas小鸟飞行游戏
  7. 启动bat文件--系统找不到指定路径
  8. 假如不小心因病去世,怎么给家人留下足够的财富呢?
  9. 效能篇 | 爱奇艺APP一键体检技术实践
  10. 【云原生之Docker实战】使用Docker部署phpMyAdmin数据库管理工具