文档章节

ElasticSearch里面关于日期的存储方式

九劫散仙
 九劫散仙
发布于 2017/04/01 14:05
字数 1560
阅读 78
收藏 1

在ElasticSearch里面最常用的就是时间字段了,经常会在群里看到一些小伙伴提出有关时间的问题,为什么es查询的时间跟我实际看到的时间差8个小时呢。如果我们了解了ElasticSearch底层的时间存储方式就会比较容易的理解这个问题。

下面散仙先普及下时区的知识,想必大家也不陌生学过地理的同学都知道全球有24个时区每个时区的跨度是经度15度,

相较于两地时间表,可以显示世界各时区时间和地名的世界时区表(World Time),就显得精密与复杂多了,通常世界时区表的表盘上会标示着全球24个时区的城市名称,但究竟这24个时区是如何产生的?过去世界各地原本各自订定当地时间,但随着交通和电讯的发达,各地交流日益频繁,不同的地方时间,造成许多困扰,于是在西元1884年的国际会议上制定了全球性的标准时,明定以英国伦敦格林威治这个地方为零度经线的起点(亦称为本初子午线),并以地球由西向东每24小时自转一周360°,订定每隔经度15°,时差1小时。而每15°的经线则称为该时区的中央经线,将全球划分为24个时区,其中包含23个整时区及180°经线左右两侧的2个半时区 就全球的时间来看,东经的时间比西经要早,也就是如果格林威治时间是中午12时,则中央经线15°E的时区为下午1时,中央经线30°E时区的时间为下午2时;反之,中央经线15°W的时区时间为上午11时,中央经线30°W时区的时间为上午10时。以台湾为例,台湾位于东经121°,换算后与格林威治就有8小时的时差。如果两人同时从格林威治的0°各往东、西方前进,当他们在经线180°时,就会相差24小时,所以经线180°被定为国际换日线,由西向东通过此线时日期要减去一日,反之,若由东向西则要增加一日。

几个时间名词:

(1)GMT:格林威治标准时间

(2)UTC:世界协调时间

(3)DST:夏日节约时间

(4)CST:中国标准时间

其中GMT时间可以近似认为和UTC时间是相等的,但从精度上来说UTC时间更精确。其误差值必须保持在0.9秒以内

CST= GMT + 8 =UTC + 8

从上面可以看出来中国的时间是等于UTC时间+8小时,es默认存储时间的格式是UTC时间,如果我们查询es然后获取时间日期默认的数据,会发现跟当前的时间差8个小时,这其实是正常的,因为es默认存储是用的UTC时间,所以我们需要做的就是读取long型时间戳,然后重新格式化成下面的时间戳,即可获得正确的时间

yyyy-MM-dd HH:mm:ss

像差8个时区的事情,最容易见到的就是,我们使用logstash收集的日志,发送到es里面,然后通过head查询就能发现不一致,但是如果我们用kibana查询,就不会发现时区问题,为什么? 因为kibana已经处理时区问题了,所以在kibana的页面显示的时间是正确的。

此外在使用Java Client聚合查询日期的时候,需要注意时区问题,因为默认的es是按照UTC标准时区算的,所以不设置的聚合统计结果是不正确的。

在es的DateHistogramBuilder里面有几个比较重要的参数:

field:指定按那个字段聚合
interval:聚合的时间单位(年,季度,月,周,天,小时,分钟,秒)
format:日期格式
time_zone:时区指定
offset:时间偏移量

注意,默认不设置时区参数,es是安装UTC的时间进行查询的,所以分组的结果可能与预期不一样,所以我们要指定时区为Asia/Shanghai代表北京的时区,这样才能获取正确的聚合结果

curl方式如下:

GET my_index/_search?size=0
{
  "aggs": {
    "by_day": {
      "date_histogram": {
        "field":     "ctime",
        "interval":  "day",
        "time_zone": "Asia/Shanghai"
      }
    }
  }
}

Java代码如下:

     SearchRequestBuilder search = client.prepareSearch("search2017-02*").setTypes("log");
        DateHistogramBuilder dateagg = AggregationBuilders.dateHistogram("dateagg");
        dateagg.field("ctime");//聚合时间字段
        dateagg.interval(DateHistogramInterval.DAY);//按天聚合第一天的0点到第二天的0点
        dateagg.timeZone("Asia/Shanghai");//指定时区
//      dateagg.offset("+8h");//默认都是从0点开始计算一天的,通过这个offset,我们可以把第一天的6点到第二天的6点当做一天来聚合
        search.addAggregation(dateagg);

        Histogram hs= search.get().getAggregations().get("dateagg");
        List<Histogram.Bucket> buckets =   (List<Histogram.Bucket>) hs.getBuckets();//获取结果
        for(Histogram.Bucket bk:buckets){
        //下面的转化,也是因为默认是UTC的时间,所以我们要获取时间戳,自己转化
            System.out.println(new DateTime(Long.parseLong(bk.getKeyAsString()+"")).toString("yyyy-MM-dd HH:mm:ss") +"  "+bk.getDocCount());
        }
        client.close();

上面的这个例子,基本涵盖了日期聚合核心功能,其中时区和偏移量时两个非常有用的而且需要特别注意的参数,不设置时区直接统计结果肯定是不准确的,offset偏移量这个参数,在某些时刻也是有用的,它可以自己定义一天的开始,比如设置从第一天的3点到第二天的3点为一天,默认都是从0点开始0点结束算做一天的,最后一点需要注意的是在输出打印时间的时候也要考虑转化因为默认也是UTC的时间,所以我们直接取出时间戳,自己格式化时间即可。

官网文档:

https://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-bucket-datehistogram-aggregation.html

有什么问题可以扫码关注微信公众号:我是攻城师(woshigcs),在后台留言咨询。 技术债不能欠,健康债更不能欠, 求道之路,与君同行。

输入图片说明

© 著作权归作者所有

共有 人打赏支持
九劫散仙
粉丝 266
博文 175
码字总数 189625
作品 0
海淀
私信 提问
Elastic 在年度用户大会 Elastic{ON} 2018 上发布众多新功能和技术预览

下载超过 2.25 亿次,Elastic 公开 X-Pack 源代码 旧金山 (Elastic{ON} 2018) – 2018 年 2 月 27 日 – Elastic,Elasticsearch 和 Elastic Stack背后的公司,今天宣布其产品累计下载次数达...

Medcl
2018/03/01
0
0
Elasticsearch 日期查询详解,Elasticsearch Date 查询Java API

Elasticsearch 日期存储 Java API 存储的时候,我采用的方式是直接存储 类型。上部分代码。 如果有日期查询,大量的日期查询,建议想清楚,是以 , ,还是 类型的毫秒值,怎么存储怎么查询。...

xiaomin0322
2018/06/22
0
0
centos 7( linux )下安装elasticsearch教程

目录 概述 环境准备 elaticsearch简介 安装elasticsearch 彩蛋 概述 很久没有写博客了,最近在做全文检索的项目,发现elasticsearch踩了不少坑,百度点进去又是坑,在此记录一下自己的踩坑历程。...

java_龙
2018/10/15
0
0
Elasticsearch简介与实战

什么是Elasticsearch?   Elasticsearch是一个开源的分布式、RESTful 风格的搜索和数据分析引擎,它的底层是开源库Apache Lucene。   Lucene 可以说是当下最先进、高性能、全功能的搜索引...

但盼风雨来_jc
03/06
0
0
ElasticSearch开发问题汇总(不断更新中)

1、Mapping: [译]ElasticSearch数据类型--string类型已死, 字符串数据永生 ElasticSearch动态日期映射 2、Spring Data Elasticsearch: Spring Data Elasticsearch教程...

九州暮云
2018/07/18
0
0

没有更多内容

加载失败,请刷新页面

加载更多

生产者消费者问题(PV操作)

一、明确定义 要理解生产消费者问题,首先应弄清PV操作的含义:PV操作是由P操作原语和V操作原语组成(原语是不可中断的过程),对信号量进行操作,具体定义如下: P(S):①将信号量S的值减...

shzwork
5分钟前
0
0
重新认识网络通信协议

OSI网络分层 应用层 http, smtp,pop3这些都属于应用层协议 为用户的应用程序提供服务 表示层 确保一个系统的应用层发送的信息被另一个系统的应用层接收到 会话层 通过传输层建立数据传输的通...

最胖的瘦子
16分钟前
0
0
【转】分布式数据流的轻量级异步快照

本篇翻译自论文:Lightweight Asynchronous Snapshots for Distributed Dataflows,Flink的容错快照模型即来源于该论文。原文地址:https://arxiv.org/pdf/1506.08603.pdf 分布式数据流的轻量...

yiduwangkai
19分钟前
0
0
java使用反射机制设置私有成员变量的值

写一个方法:public void setProperty(Objectobj, String propertyName, Object value){}, 此方法可将obj对象中名为propertyName的属性的值设置为value。(这里不知道obj对象的propertyNam...

群星纪元
25分钟前
0
0
用 Tapestry 的方式在页面模板中加入注释

<span jwcid="$remove$">这里是注释</span>

LeoXu
25分钟前
0
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部