日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Elasticsearch时区问题

發布時間:2023/12/20 编程问答 20 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Elasticsearch时区问题 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

發現問題

  • 創建索引,配置date類型字段
  • 批量插入數據,格式分別為帶時區信息,不帶時區信息,時間戳
  • 對數據進行聚合
  • 對數據進行查詢,分別使用帶時區信息,不帶時區信息,時間戳三種格式
  • 創建索引,配置字段類型

    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时区问题的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。