`
qindongliang1922
  • 浏览: 2188885 次
  • 性别: Icon_minigender_1
  • 来自: 北京
博客专栏
7265517b-f87e-3137-b62c-5c6e30e26109
证道Lucene4
浏览量:117670
097be4a0-491e-39c0-89ff-3456fadf8262
证道Hadoop
浏览量:126075
41c37529-f6d8-32e4-8563-3b42b2712a50
证道shell编程
浏览量:60034
43832365-bc15-3f5d-b3cd-c9161722a70c
ELK修真
浏览量:71402
社区版块
存档分类
最新评论

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

    博客分类:
  • ELK
阅读更多
在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),在后台留言咨询。
技术债不能欠,健康债更不能欠, 求道之路,与君同行。



1
0
分享到:
评论

相关推荐

    最新版linux elasticsearch-8.3.3-linux-x86_64.tar.gz

    Elasticsearch是一个开源的全文搜索引擎,它以分布式、RESTful方式工作,并且具有实时分析的能力。这个最新的Linux版本,即elasticsearch-8.3.3-linux-x86_64.tar.gz,是专为64位Linux系统设计的。Elasticsearch在...

    logstah-6.5.4

    Logstash 主要用于从各种不同来源采集日志和其他类型的数据,对其进行过滤、转换,并将结果发送到各种目的地,如 Elasticsearch 进行存储和搜索,或者其他的输出目标。 标题 "logstash-6.5.4" 指的是 Logstash 的...

    数据库系统-工作交接

    搜索引擎如Elasticsearch或Solr也可能被集成进来,提供更高效、智能的全文搜索能力。 交接过程涉及数据的安全性和权限管理。系统可能有严格的权限控制机制,确保只有授权人员可以访问和修改敏感数据。角色基础的...

    vb.net2.0_Lucene_test.rar_lucene_lucene vb.n_lucene.net vb

    10. **扩展性**:如果项目规模较大,可能还需要考虑如何分布式部署Lucene,使用如Solr或Elasticsearch这样的分布式搜索服务。 通过研究提供的代码和文档,开发者可以深入理解Lucene.NET在VB.NET中的应用,提升搜索...

    s7-300调用系统时间以及基于sm331模拟量输入模块的pt100的接线方法.doc

    SFC 1的功能为读取系统时间,参数声明数据类型存储区描述RET_VAL OUTPUT INT,I、Q、M、D、L如果在功能执行期间出错,返回值会包含故障代码CDT OUTPUT DTD、LCDT输出当前日期和时间值。 5. 数据存储格式: 在DB快...

    logback例子

    10. **日志审计**:Logback还可以与Sentry、ELK Stack(Elasticsearch, Logstash, Kibana)等工具集成,实现日志的集中管理和分析,以进行故障排查和性能监控。 通过学习和运行"Logback-demos",开发者可以深入理解...

    黑马程序员 安卓学院 万元哥项目经理 分享220个代码实例

    |--RadioGroup的用法(里面的成员可以是任何view) |--SD卡之计算剩余空间 |--Spinner下拉菜单组件 |--SplashActivity |--StringUtils工具类的常用方法 |--TabHost一个界面显示多Activity |--TextView单行跑马灯效果 |...

    assg-no-05

    由于“assg”是“assignment”的缩写,我们可以推测这可能是一个关于JavaScript编程的作业。 【描述】:“assg-no-05”描述为空,没有提供具体的作业内容。在实际情况下,这样的描述可能会包含作业的目标、要求、...

    计算机应用技术(实用手册)

    内存模块上的EEPROM (只读存储器) 储存有关模块的重要参数信息,例如内存类型、大小、速度、电压接口及模块储存区域。 CAS Latency Time: 这个项目可控制DRAM读取指令与数据成为真正可用的时间之间的延迟时间。...

    17022021_11v

    标题“17022021_11v”可能是某个项目或更新的标识,日期部分17022021可能指的是2021年2月17日,而“11v”可能是版本号或者开发迭代的标识。描述中的"Tatjana Grencione Es esmu izcils programtajs"是拉脱维亚语,意...

    javascript入门笔记

    调用:在JS中任何的合法位置处,都可以通过 函数名() 的方式进行调用 练习: 1、声明一个函数,名称为 change 2、在函数中 1、通过弹框,分两次,录入两个数字,保存在 a 和 b 2、先打印 a 和 b的值 3、如果...

Global site tag (gtag.js) - Google Analytics