ElasticSearch里面关于日期的存储方式,解决差8个小时
生活随笔
收集整理的這篇文章主要介紹了
ElasticSearch里面关于日期的存储方式,解决差8个小时
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
在ElasticSearch里面最常用的就是時間字段了,經(jīng)常會在群里看到一些小伙伴提出有關時間的問題,為什么es查詢的時間跟我實際看到的時間差8個小時呢。如果我們了解了ElasticSearch底層的時間存儲方式就會比較容易的理解這個問題。?
下面散仙先普及下時區(qū)的知識,想必大家也不陌生學過地理的同學都知道全球有24個時區(qū)每個時區(qū)的跨度是經(jīng)度15度,?
相較于兩地時間表,可以顯示世界各時區(qū)時間和地名的世界時區(qū)表(World Time),就顯得精密與復雜多了,通常世界時區(qū)表的表盤上會標示著全球24個時區(qū)的城市名稱,但究竟這24個時區(qū)是如何產(chǎn)生的?過去世界各地原本各自訂定當?shù)貢r間,但隨著交通和電訊的發(fā)達,各地交流日益頻繁,不同的地方時間,造成許多困擾,于是在西元1884年的國際會議上制定了全球性的標準時,明定以英國倫敦格林威治這個地方為零度經(jīng)線的起點(亦稱為本初子午線),并以地球由西向東每24小時自轉一周360°,訂定每隔經(jīng)度15°,時差1小時。而每15°的經(jīng)線則稱為該時區(qū)的中央經(jīng)線,將全球劃分為24個時區(qū),其中包含23個整時區(qū)及180°經(jīng)線左右兩側的2個半時區(qū)?
就全球的時間來看,東經(jīng)的時間比西經(jīng)要早,也就是如果格林威治時間是中午12時,則中央經(jīng)線15°E的時區(qū)為下午1時,中央經(jīng)線30°E時區(qū)的時間為下午2時;反之,中央經(jīng)線15°W的時區(qū)時間為上午11時,中央經(jīng)線30°W時區(qū)的時間為上午10時。以臺灣為例,臺灣位于東經(jīng)121°,換算后與格林威治就有8小時的時差。如果兩人同時從格林威治的0°各往東、西方前進,當他們在經(jīng)線180°時,就會相差24小時,所以經(jīng)線180°被定為國際換日線,由西向東通過此線時日期要減去一日,反之,若由東向西則要增加一日。?
幾個時間名詞:?
GMT:格林威治標準時間?
UTC:世界協(xié)調時間?
DST:夏日節(jié)約時間?
CST:中國標準時間?
其中GMT時間可以近似認為和UTC時間是相等的,但從精度上來說UTC時間更精確。其誤差值必須保持在0.9秒以內?
CST= GMT + 8 =UTC + 8?
此外在使用Java Client聚合查詢日期的時候,需要注意時區(qū)問題,因為默認的es是按照UTC標準時區(qū)算的,所以不設置的聚合統(tǒng)計結果是不正確的。?
官網(wǎng)文檔:?
https://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-bucket-datehistogram-aggregation.html ?
下面散仙先普及下時區(qū)的知識,想必大家也不陌生學過地理的同學都知道全球有24個時區(qū)每個時區(qū)的跨度是經(jīng)度15度,?
相較于兩地時間表,可以顯示世界各時區(qū)時間和地名的世界時區(qū)表(World Time),就顯得精密與復雜多了,通常世界時區(qū)表的表盤上會標示著全球24個時區(qū)的城市名稱,但究竟這24個時區(qū)是如何產(chǎn)生的?過去世界各地原本各自訂定當?shù)貢r間,但隨著交通和電訊的發(fā)達,各地交流日益頻繁,不同的地方時間,造成許多困擾,于是在西元1884年的國際會議上制定了全球性的標準時,明定以英國倫敦格林威治這個地方為零度經(jīng)線的起點(亦稱為本初子午線),并以地球由西向東每24小時自轉一周360°,訂定每隔經(jīng)度15°,時差1小時。而每15°的經(jīng)線則稱為該時區(qū)的中央經(jīng)線,將全球劃分為24個時區(qū),其中包含23個整時區(qū)及180°經(jīng)線左右兩側的2個半時區(qū)?
就全球的時間來看,東經(jīng)的時間比西經(jīng)要早,也就是如果格林威治時間是中午12時,則中央經(jīng)線15°E的時區(qū)為下午1時,中央經(jīng)線30°E時區(qū)的時間為下午2時;反之,中央經(jīng)線15°W的時區(qū)時間為上午11時,中央經(jīng)線30°W時區(qū)的時間為上午10時。以臺灣為例,臺灣位于東經(jīng)121°,換算后與格林威治就有8小時的時差。如果兩人同時從格林威治的0°各往東、西方前進,當他們在經(jīng)線180°時,就會相差24小時,所以經(jīng)線180°被定為國際換日線,由西向東通過此線時日期要減去一日,反之,若由東向西則要增加一日。?
幾個時間名詞:?
CST= GMT + 8 =UTC + 8?
從上面可以看出來中國的時間是等于UTC時間+8小時,es默認存儲時間的格式是UTC時間,如果我們查詢es然后獲取時間日期默認的數(shù)據(jù),會發(fā)現(xiàn)跟當前的時間差8個小時,這其實是正常的,因為es默認存儲是用的UTC時間,所以我們需要做的就是讀取long型時間戳,然后重新格式化成下面的時間戳,即可獲得正確的時間 :
yyyy-MM-dd HH:mm:ss 像差8個時區(qū)的事情,最容易見到的就是,我們使用logstash收集的日志,發(fā)送到es里面,然后通過head查詢就能發(fā)現(xiàn)不一致,但是如果我們用kibana查詢,就不會發(fā)現(xiàn)時區(qū)問題,為什么? 因為kibana已經(jīng)處理時區(qū)問題了,所以在kibana的頁面顯示的時間是正確的。?此外在使用Java Client聚合查詢日期的時候,需要注意時區(qū)問題,因為默認的es是按照UTC標準時區(qū)算的,所以不設置的聚合統(tǒng)計結果是不正確的。?
在es的DateHistogramBuilder里面有幾個比較重要的參數(shù):
field:指定按那個字段聚合 interval:聚合的時間單位(年,季度,月,周,天,小時,分鐘,秒) format:日期格式 time_zone:時區(qū)指定 offset:時間偏移量注意,默認不設置時區(qū)參數(shù),es是安裝UTC的時間進行查詢的,所以分組的結果可能與預期不一樣,所以我們要指定時區(qū)為Asia/Shanghai代表北京的時區(qū),這樣才能獲取正確的聚合結果?
curl方式如下:?
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");//指定時區(qū) 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(); 上面的這個例子,基本涵蓋了日期聚合核心功能,其中時區(qū)和偏移量時兩個非常有用的而且需要特別注意的參數(shù),不設置時區(qū)直接統(tǒng)計結果肯定是不準確的,offset偏移量這個參數(shù),在某些時刻也是有用的,它可以自己定義一天的開始,比如設置從第一天的3點到第二天的3點為一天,默認都是從0點開始0點結束算做一天的,最后一點需要注意的是在輸出打印時間的時候也要考慮轉化因為默認也是UTC的時間,所以我們直接取出時間戳,自己格式化時間即可。?官網(wǎng)文檔:?
https://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-bucket-datehistogram-aggregation.html ?
總結
以上是生活随笔為你收集整理的ElasticSearch里面关于日期的存储方式,解决差8个小时的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【算法】五分钟快速了解代码复杂度
- 下一篇: 【机器学习】全面归纳距离和相似度方法(7