您的位置:首页 > 其它

Elasticsearch Date类型数据默认格式:将数据写入es的时间后再读取出来缺少8小时原因

2018-06-26 10:55 2001 查看

一、问题描述

把想要的数据通过同步工具从MySQL中写入es中存储,然后从搜索后台管理系统读取数据列表,发现时间显示比数据库中显示的时间要提前8小时。

二、问题分析

首先在索引里面查看了时间数据的存储格式为世界时间,默认是0时区,但是我们一般用的是北京时间东八区,因此间隔了八小时。


直接转过来的时间是:


但实际上数据库里面存储的时间是:


我们需要最终显示的是时间是和存在数据库中的北京时间一致。

搜索的数据来源于存储在elasticsearch里面的数据,因此可以从数据源(存储在es里面的数据)、后台处理、前端处理三种方法处理0时区的数据。

三、解决方案

1、最好的办法是改变数据源,也就是在使用同步工具的时候,写入es中的时间数据是通用时间yyyy-MM-dd HH:mm:ss 格式的数据。

我这边使用的是公司产品adapter同步数据,其中有一个写入数据到elasticsearch中的插件。

如果不对数据做任何处理,写入elastic中的数据会自动转换成GMT,默认0时区,因此现在要做的事情就是修改同步工具elasticsearch插件的源代码。

在获取MySQL中的数据后根据数据类型对Date类型数据进行处理(部分代码):

if(data instanceof Date) {
SimpleDateFormat fm= new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
data= fm.format(data);
}

record.put(targetField.getFieldName(), data);

注意事项:es支持的日期格式

https://www.elastic.co/guide/en/elasticsearch/reference/2.3/mapping-date-format.html

其中并未含有yyyy-MM-dd HH:mm:ss 格式,因此需要格式化时间。

在es中,date类型的默认格式为:"strict_date_optional_time||epoch_millis"

在写入es的时候,格式化了时间,因此在mapping中的时间格式要增加yyyy-MM-dd HH:mm:ss的格式。


2、在代码中获取到es中的数据后转格式。

直接转为通用格式yyyy-MM-dd HH:mm:ss的话,时间是少8小时的,因此解决办法为,将时区默认为0时区。(不推荐)

sdf.setTimeZone(TimeZone.getTimeZone("GMT"));

3、前端处理,方法同上,或者转换时间时加上8小时,但是这个会有一个问题,遇到零点、月底、年底、闰年时,需要对应的进一位,处理起来比较麻烦,因此不推荐。

四、总结

处理问题时一般最好从源头解决问题。

处理方案参考文章:Elasticsearch Date类型,时间存储相关说明

阅读更多
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐