elasticsearch 计算时间差多少

在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°被定为国际换日线,由西向东通过此线时日期要减去一日反之,若由東向西则要增加一日 

几个时间名词: 


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

從上面可以看出来中国的时间是等于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标准时区算的,所以不设置的聚合统计结果是不正确的 

field:指定按那个字段聚合 
interval:聚合的时間单位(年,季度月,周天,小时分钟,秒) 
 
注意默认不设置时区参数,es是安装UTC的时间进行查询的所以分组的结果可能与预期鈈一样,所以我们要指定时区为Asia/Shanghai代表北京的时区这样才能获取正确的聚合结果







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

你最好的选择是脚本字段如果您启用了动态脚本,并且这些日期字段在映射中定义为日期则上述搜索查询应该可以工作。

请注意你会得到结果在时代,你需要转换為你的面额

您可以在这里阅读约及其一些例子。

这篇文章主要向大家介绍[Elasticsearch] 聚合 - 时間数据处理(Looking at Time),主要内容包括基础应用、实用技巧、原理机制等方面希望对大家有所帮助。

若是在ES中搜索是最多见的行为,那么建立日期柱状图(Date Histogram)确定是第二常见的为何要使用日期柱状图呢?git

想象在你的数据中有一个时间戳数据是什么不重要-Apache日志事件,股票交易日期棒浗比赛时间-任何拥有时间戳的数据都能经过日期柱状图受益。当你有时间戳时你常常会想建立基于时间的指标信息:github

  • 今年的每月销售了哆少辆车?json

  • 过去的12小时中这只股票的价格是多少?服务器

  • 上周每一个小时咱们的网站的平均延迟是多少elasticsearch

常规的histogram一般使用条形图来表示,而date histogram倾向于被装换为线图(Line Graph)来表达时间序列(Time Series)不少公司使用ES就是为了对时间序列数据进行分析。ide

date_histogram的工做方式和常规的histogram相似常规的histogram是基于数徝字段来建立数值区间的桶,而date_histogram则是基于时间区间来建立桶所以每一个桶是按照某个特定的日历时间定义的(好比,1个月或者是2.5天)oop

常规Histogram鈳以和日期一块儿使用吗?网站

从技术上而言是能够的。常规的histogram桶能够和日期一块儿使用可是,它并懂日期相关的信息(Not calendar-aware)而对于date_histogram,你能够将间隔(Interval)指定为1个月它知道2月份比12月份要短。date_histogram还可以和时区一同工做所以你能够根据用户的时区来对图形进行定制,而不是根据服務器ui

常规的histogram会将日期理解为数值,这意味着你必须将间隔以毫秒的形式指定同时聚合也不理解日历间隔,因此它对于日期几乎是无法使用的

第一个例子中,咱们会建立一个简单的线图(Line Chart)来回答这个问题:每月销售了多少辆车

在查询中有一个聚合,它为每月建立了一个桶它可以告诉咱们每月销售了多少辆车。同时指定了一个额外的格式参数让桶拥有更"美观"的键值在内部,日期被简单地表示成数值嘫而这会让UI设计师生气,所以使用格式参数可让日期以更常见的格式进行表示

获得的响应符合预期,可是也有一点意外(看看你可以察觉箌):

聚合完整地被表达出来了你能看到其中有用来表示月份的桶,每一个桶中的文档数量以及漂亮的key_as_string。

发如今上面的响应中的奇怪之處了吗

是的,咱们缺失了几个月!默认状况下date_histogram(以及histogram)只会返回文档数量大于0的桶。

这意味着获得的histogram响应是最小的可是有些时候该行为並非咱们想要的。对于不少应用而言你须要将获得的响应直接置入到一个图形库中,而不须要任何额外的处理

所以本质上,咱们须要返回全部的桶哪怕其中不含有任何文档。咱们能够设置两个额外的参数来实现这一行为:

这两个参数会强制返回该年中的全部月份不管它们的文档数量是多少。min_doc_count的意思很容易懂:它强制返回哪怕为空的桶

extended_bounds参数须要一些解释。min_doc_count会强制返回空桶可是默认ES只会返回在你的數据中的最小值和最大值之间的桶。

所以若是你的数据分布在四月到七月你获得的桶只会表示四月到七月中的几个月(可能为空,若是使鼡了min_doc_count=0)为了获得一全年的桶,咱们须要告诉ES须要获得的桶的范围

extended_bounds参数就是用来告诉ES这一范围的。一旦你添加了这两个设置获得的响应僦很容易被图形生成库处理而最终获得下图:


咱们已经看到过不少次,为了实现更复杂的行为桶能够嵌套在桶中。为了说明这一点咱們会建立一个用来显示每一个季度,全部制造商的总销售额的聚合同时,咱们也会在每一个季度为每一个制造商单独计算其总销售额所以咱们可以知道哪一种汽车创造的收益最多:

获得的响应以下(删除了不少):

咱们能够将该响应放入到一个图形中,使用一个线图(Line Chart)来表达總销售额一个条形图来显示每一个制造商的销售额(每一个季度),以下所示:


显然它们都是简单的例子可是在对聚合进行绘图时,是存茬无限的可能性的好比,下图是Kibana中的一个用来进行实时分析的仪表板它使用了不少聚合:

由于聚合的实时性,相似这样的仪表板是很嫆易进行查询操做和交互的。这让它们很是适合非技术人员和分析人员对数据进行分析而不须要他们建立一个Hadoop任务。


我要回帖

 

随机推荐