【ES实战】初探ES date类型的时区机制

这篇具有很好参考价值的文章主要介绍了【ES实战】初探ES date类型的时区机制。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

初探ES date类型的时区机制


ES默认date类型的 format格式为: strict_date_optional_time||epoch_millis

时间范围查询示例

gt:大于

gte:大于等于

lt:小于

lte:小于等于

GET _search
{
    "query": {
        "range" : {
                "gte": "01/01/2012",
                "lte": "2013",
                "format": "dd/MM/yyyy||yyyy"
        }
    }
}

验证场景

date字段类型指定唯一字符串的日期格式(非默认)

# 创建索引-指定单一的日期格式,不指定时区。
PUT gudongtest001
{
    "settings": {
        "number_of_replicas": 0
    },
    "mappings": {
        "_doc": {
            "properties": {
                "date": {
                    "type": "date",
                    "format": "yyyy-MM-dd HH:mm:ss",
                    "store": true
                },
                "message": {
                    "type": "keyword"
                }
            }
        }
    }
}

# 写入数据

PUT gudongtest001/_doc/1
{ "date": "2023-02-28 00:01:10","message":"trying out Elasticsearch" } 

PUT gudongtest001/_doc/2
{ "date": "2023-02-28 09:01:10","message":"trying out Elasticsearch" } 

PUT gudongtest001/_doc/3
{ "date": "2023-02-28 18:01:10","message":"trying out Elasticsearch" } 

# 不满足日期格式的数据无法写入了
PUT gudongtest001/_doc/4
{ "date": "1677722733000","message":"trying out Elasticsearch" } 

# 查询
# 正常查询与显示
GET gudongtest001/_search
{
    "query": {
        "range" : {
            "date" : {
                "gte" : "2023-02-28 00:01:10"
            }
        }
    }
}

# 查询过程中进行format -1677513670000在东八区的时间为2023-02-28 00:01:10
GET gudongtest001/_search
{
    "query": {
        "range" : {
            "date" : {
                "gte" : "1677513670000",
                "format": "epoch_millis"
            }
        }
    }
}

# 以上查询数据是没问题的

date类型采用默认的格式

PUT gudongtest002
{
    "settings": {
        "number_of_replicas": 0
    },
    "mappings": {
        "_doc": {
            "_all": {
                "enabled": false
            },
            "properties": {
                "date": {
                    "type": "date",
                    "store": true
                },
                "message": {
                    "type": "keyword"
                }
            }
        }
    }
}

# 写入数据
# 不支持非UTC格式的数据写入
PUT gudongtest002/_doc/1
{ "date": "2023-02-28 00:01:10","message":"trying out Elasticsearch" } 

PUT gudongtest002/_doc/1
{ "date": "1677513670000","message":"trying out Elasticsearch" } 

PUT gudongtest002/_doc/2
{ "date": "1677546070000","message":"trying out Elasticsearch" } 

PUT gudongtest002/_doc/3
{ "date": "1677578470000","message":"trying out Elasticsearch" } 

# 查询数据
GET gudongtest002/_search
{
    "query": {
        "range" : {
            "date" : {
                "gte" : "1677513670000"
            }
        }
    }
}

# 查询数据 id:1的记录没有查询到
GET gudongtest002/_search
{
    "query": {
        "range" : {
            "date" : {
                "gte" : "2023-02-28 00:01:10",
                 "format": "yyyy-MM-dd HH:mm:ss"
            }
        }
    }
}

# 查看数据存储情况
GET gudongtest002/_search
{
    "stored_fields": [
        "date"
    ],
    "query": {
        "match_all": {}
    }
}

## id:2 date:"2023-02-28T01:01:10.000Z"  1677546070000
## id:1 date:"2023-02-27T16:01:10.000Z"  1677513670000
## id:3 date:"2023-02-28T10:01:10.000Z"  1677578470000
### 可以发现 对于unixtime时间戳在存入ES的时候,采用的是0时区。索引id1在es中的时间不满足查询条件,所以没有查询到。

# 查询是带上时区,这个时区是作于用存储数据的,并未是查询条件。
GET gudongtest002/_search
{
    "query": {
        "range" : {
            "date" : {
                "gte" : "2023-02-28 00:01:10",
                 "format": "yyyy-MM-dd HH:mm:ss",
                 "time_zone": "+08:00"
            }
        }
    }
}

date类型采用混合时间格式

PUT gudongtest003
{
    "settings": {
        "number_of_replicas": 0
    },
    "mappings": {
        "_doc": {
            "_all": {
                "enabled": false
            },
            "properties": {
                "date": {
                    "type": "date",
                    "format": "yyyy-MM-dd HH:mm:ss||epoch_millis",
                    "store": true
                },
                "message": {
                    "type": "keyword"
                }
            }
        }
    }
}

# 满足任一格式既可以写入
PUT gudongtest003/_doc/1
{ "date": "2023-02-28 00:01:10","message":"trying out Elasticsearch" } 

PUT gudongtest003/_doc/2
{ "date": "1677513670000","message":"trying out Elasticsearch" } 

PUT gudongtest003/_doc/3
{ "date": "1677546070000","message":"trying out Elasticsearch" } 

PUT gudongtest003/_doc/4
{ "date": "1677578470000","message":"trying out Elasticsearch" } 


# 使用时间戳查询没问题
GET gudongtest003/_search
{

    "query": {
        "range" : {
            "date" : {
                "gte" : "1677513670000"
            }
        }
    }
}

# 使用字符串查询--会出现同样的问题-查询的时候需要增加上时区,即查询条件时间代表的时区
GET gudongtest003/_search
{
    "stored_fields": [
        "date"
    ],
    "query": {
        "range": {
            "date": {
                "gte": "2023-02-28 00:01:10",
                "time_zone": "+08:00"
            }
        }
    }
}

# 上述查询的时候_id为2的记录查询不到
GET gudongtest003/_doc/2/_explain
{
    "query": {
        "range": {
            "date": {
                "gte": "2023-02-28 00:01:10",
                "lt": "2023-03-01 00:01:10"
            }
        }
    }
}

{
    "_index": "gudongtest003",
    "_type": "_doc",
    "_id": "2",
    "matched": false,
    "explanation": {
        "value": 0,
        "description": "date:[1677542470000 TO 1677628869999] doesn't match id 0",
        "details": []
    }
}

1677542470000(2023-02-28 08:01:10) to 1677628869999(2023-03-01 08:01:09)
# 查询时,查询条件的时间字符转成的,采用的是0时区。而id2中date是1677513670000,就无法满足了。

time_zone参数对写入时 是否有作用

PUT gudongtest004
{
    "settings": {
        "number_of_replicas": 0
    },
    "mappings": {
        "_doc": {
            "_all": {
                "enabled": false
            },
            "properties": {
                "date": {
                    "type": "date",
                    "format": "yyyy-MM-dd HH:mm:ss",
                    "store": true
                },
                "message": {
                    "type": "keyword",
                    "doc_values": false
                }
            }
        }
    }
}

#写入数据
PUT gudongtest004/_doc/1
{
    "date": "2023-02-28 00:01:10",
    "message": "trying out Elasticsearch",
    "time_zone": "+08:00"
}

PUT gudongtest004/_doc/2
{
    "date": "2023-02-28 00:01:10",
    "message": "trying out Elasticsearch"
}

PUT gudongtest004/_doc/3
{ "date": "1677546070000","message":"trying out Elasticsearch" } 

PUT gudongtest004/_doc/4
{ "date": "1677546070000","message":"trying out Elasticsearch","time_zone": "+08:00" } 

# 查看数据存储情况
GET gudongtest004/_search
{
    "stored_fields": [
        "date"
    ],
    "query": {
        "match_all": {}
    }
}



## id:2 date:"2023-02-28 00:01:10"  1677546070000
## id:1 date:"2023-02-28 00:01:10"  1677513670000
## id:3 date:"2023-02-28 01:01:10"  1677546070000
## id:4 date:"2023-02-28 01:01:10"  1677546070000
### "time_zone": "+08:00" 形式的时区参数无效

#有作用的方式之一
POST gudongtest004/_doc/5
{
  "date":"2019-12-11T08:00:00+08:00"
}

小结

  • 创建索引的时候无法指定时区
  • 采用单一字符串格式时,写入和查询是可以忽略时区。
  • ES内部的时区是0时区
  • 写入字符串没问题,写入时间戳时会少八个小时(因为我们在东八区)
  • 在时间戳与字符串格式混用的场景下,最好查询时,统一以时间戳作为查询条件。
  • 混用多个字符串格式没有问题,尽量不要混时间戳

彩蛋:在_ingest中结合timezone控制写入时区文章来源地址https://www.toymoban.com/news/detail-605608.html

PUT _ingest/pipeline/chage_utc_to_asiash
{
  "processors": [
    {
      "date" : {
        "field" : "my_time",
        "target_field": "my_time", 
        "formats" : ["yyyy-MM-dd HH:mm:ss"],
        "timezone" : "Asia/Shanghai"
      }
    }
  ]
}

PUT gudongtest005
{
    "settings": {
        "default_pipeline": "chage_utc_to_asiash",
        "number_of_replicas": 0
    },
    "mappings": {
        "_doc": {
            "properties": {
                "my_time": {
                    "type": "date"
                }
            }
        }
    }
}

PUT gudongtest005/_doc/1
{
  "my_time": "2021-08-09 08:07:16"
} 

GET gudongtest005/_search
{
    "query": {
        "match_all": {}
    }
}

 "my_time": "2021-08-09T08:07:16.000+08:00"

到了这里,关于【ES实战】初探ES date类型的时区机制的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包赞助服务器费用

相关文章

  • Linux中关于日期和时区的操作(date命令、ntp程序自动校准时间)

    Linux中关于日期和时区的操作(date命令、ntp程序自动校准时间)

    语法: date [-d] [+格式化字符串] -d 按照给定的字符串显示日期,一般用于 日期计算 格式化字符串:通过特定的字符串标记,来控制显示的日期格式 %Y 年          %y 年份后两位数字 (00..99) %m 月份 (01..12) %d 日 (01..31) %H 小时 (00..23) %M 分钟 (00..59) %S 秒 (00..60) %s 自 1970-01-01

    2024年01月16日
    浏览(9)
  • ES系列--es初探

    ES系列--es初探

            一般传统数据库,全文检索都实现的很鸡肋,因为一般也没人用数据库存文本字段。进 行全文检索需要扫描整个表,如果数据量大的话即使对 SQL 的语法优化,也收效甚微。建 立了索引,但是维护起来也很麻烦,对于 insert 和 update 操作都会重新构建索引。    

    2024年02月15日
    浏览(8)
  • ES创建索引模板设置分片和副本数及时间格式问题

    ES创建索引模板设置分片和副本数及时间格式问题

    创建索引模板设置分片和副本及时间格式问题 一、创建索引模板 二、插入测试数据 三、查看索引情况(cerebro可视化插件) 查看分片和副本情况 查看字段 四、通kibana查看数据 五、最后补充下kibana设置时间格式显示问题

    2024年02月16日
    浏览(13)
  • 【ELK03】ES 索引的Mapping映射详解、数据类型和settings属性设置

    映射(MAPPING)就是es中一个决定了文档如何存储,如何生成索引,字段各种类型定义的过程.类似于我们在关系型数据库中创建一个 表格数据之前先定义表格有哪些字段,每个字段是什么类型 ,然后数据会按照这个配置写入表格,ES中同样是这个过程,它由两种映射组成.一个是 动态映射

    2024年02月03日
    浏览(11)
  • [ES]ElasticSearch中时间日期的时区探讨

            由于ES不能指定时区(也许将来会支持也说不一定),目前是时区始终是UTC。 如果存储是日期时间类型,则需考虑时区问题; 如果是字符串,除非直接比对,否则在转换为日期是会有时区问题; 如果是时间戳,即Long类型,同样需要考虑时区问题。         执行的查

    2024年02月04日
    浏览(5)
  • [ES]ElasticSearch强转日期的时区问题

            由于ES不能修改时区,且默认时区始终为UTC。         当才查询数据时,通过强转获得的日期并不是想要的,通过分析发现,正是由于默认时区导致结果相差了8个小时。         查询语句: POST http://localhost:9200/_sql?format=text         返回结果:            

    2024年02月04日
    浏览(8)
  • centos7设置时区,时间+时间同步的三种方式

    centos7设置时区,时间+时间同步的三种方式

    1.1查看当前时区: 1.2查看时间命令: 1.3选择时区命令 设置timezone的时区 3.1安装ntp 3.2启动ntp服务 3.3查看ntp服务 3.4修改ntp.conf文件 3.5重启服务 3.6检查同步状态 3.7执行硬件时间向软件时间同步 3.8查看当前时间 4.1最简单的方法,让所有集群中的主机跟某个时间服务器的 时间同步

    2024年02月04日
    浏览(13)
  • 时间字符串转Date类型

    时间字符串转Date类型

    天行健,君子以自强不息;地势坤,君子以厚德载物。 每个人都有惰性,但不断学习是好好生活的根本,共勉! 文章均为学习整理笔记,分享记录为主,如有错误请指正,共同学习进步。 将字符串时间转为Date类型的日期 如 2023年7月5号12点34分58秒的时间字符串20230705123458 转

    2024年02月12日
    浏览(18)
  • Ubuntu、CentOS 修改时区、设置24小时时间格式

    Ubuntu、CentOS 修改时区、设置24小时时间格式

     修改设置时区  方法一 tzselect 方法二 仅限于RedHat Linux 和 CentOS系统 timeconfig 方法三 适用于Debian dpkg-reconfigure tzdata 方法四 复制相应的时区文件,替换CentOS系统时区文件;或者创建链接文件 cp /usr/share/zoneinfo/EST5EDT /etc/localtime 或者 ln -s /usr/share/zoneinfo/EST5EDT /etc/localtime 时间同步

    2024年02月05日
    浏览(12)
  • Python time时间格式化以及设置时区

    Python time时间格式化以及设置时区

    Python提供了多个内置模块用于操作日期时间,像calendar,time,datetime。time模块我在之前的文章已经有所介绍,它提供 的接口与C标准库time.h基本一致。相比于time模块,datetime模块的接口则更直观、更容易调用。今天就来讲讲datetime模块。 datetime模块定义了两个常量:datetime.MI

    2024年02月08日
    浏览(13)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包