繁体   English   中英

InfluxDB2.0:如何总结具有不规则时间间隔的多个时间序列?

[英]InfluxDB2.0: How to sum up multiple time series with irregular time interval?

TL;DR我正在使用 Influxdb v2.0 并使用 Influx 查询语法(如在 GUI 中)。 我有多个数字 0/1 状态系列(相同的 _field,不同的标签),我想总结一下。 问题是状态以不规则的时间间隔存储在数据库中,这意味着在任何时候都应该使用最后一个点查询每个标签的实际实际值。 我已经尝试过使用'last'作为函数的aggregateWindow,但最后只是为没有存储点的窗口删除表。 反正我可以总结一下吗? 我接受任何方法(包括导出数据并使用其他语言脚本代替 lmao)。 先感谢您。


情景

我的团队之前已经实现了一个签入/签出系统,其中电话号码代表真实世界事件中的每个人,并决定使用 InfluxDB v2.0 作为数据库(我们选择它是为了我们可以轻松地通过 Grafana 进行监控) . 我有一个存储签入/签出值点的存储桶,所有架构都相同。 架构如下:

measurement: 'user'
tags: [phone, type]     // type is either ['normal', 'staff']
value: 0 or 1           // 0 for checking out event, 1 for checking in event

每当有人签入该事件时,就会插入一个值为 1 的点,反之亦然,每当有人签出该事件时,就会插入一个值为 0 的点。 请记住,如果用户决定再次触发 api,就像之前已经签入并再次签入一样,该点可能会重复(尽管我们认为这具有相同的状态 1)。 所以数据就像一个数字 0/1 状态,但点的时间间隔不规则,每个电话号码一条曲线图。 相同的电话号码但类型不同,对我们来说被视为不同的人。

该项目已经部署,我们的任务是对数据进行后处理。 问题是可视化整个时间的事件人口图。 从数学的角度来看,这应该可以通过将每个人的所有状态(0/1 线)随时间相加来轻松解决。 我首先在 Influx 查询中尝试了这样的事情:

from(bucket: "event_name")
  |> range(start: v.timeRangeStart, stop: v.timeRangeStop)
  |> filter(fn: (r) => r["_measurement"] == "user")
  |> group(columns: ["type"])
  |> aggregateWindow(every: v.windowPeriod, fn: sum, createEmpty: true)
  |> yield()

结果看起来非常有希望,人口图有两种颜色,类型为 normal 和 staff。 但是仔细一看,Influx 的 sum 函数其实是对每个窗口中每个点的 _value 求和的。 这意味着对于一些没有意义的窗口, sum 函数实际上并没有总结数据库中的每个人。 目标是对那些没有点的窗口的实际 _value 求和(这些窗口的 _value 应该与最后一个点的 _value 相同,例如,就像我在晚上 7 点登记的那样,所有的 _value 都应该是 1晚上 7 点以后的时间甚至某些窗口也没有任何意义)。 然后我尝试了这样的事情:

from(bucket: "event_name")
  |> range(start: v.timeRangeStart, stop: v.timeRangeStop)
  |> filter(fn: (r) => r["_measurement"] == "user")
  |> aggregateWindow(every: 1m, fn: last, createEmpty: true)
  |> fill(usePrevious: true)
  |> group(columns: ["type"])
  |> aggregateWindow(every: 1m, fn: sum)
  |> yield()

我为每个窗口使用最后一个点,然后用空的 _value 填充窗口,并使用前一个可能的点,然后再次对每个窗口的 _value 求和。 但是后来我发现last函数实际上删除了空表,这意味着没有点的窗口被删除(createEmpty 是无用的)。 然后问题的范围是我必须找到像last这样的函数但不删除空表。 我尝试过reducelast一样创建我自己的逻辑,但遗憾的是它并没有像我想要的那样(可能是我编码错了)。

如果您有任何想法,请帮忙。 非常感谢。

Nvm,我找到了解决方案,这里适用于那些处于相同情况的人,虽然在性能上不是很优雅,但这是我发现它有效的唯一查询。

from(bucket: "event_name")
  |> range(start: v.timeRangeStart, stop: v.timeRangeStop)
  |> filter(fn: (r) => r["_measurement"] == "user")
  |> aggregateWindow(every: 1m, fn: last, createEmpty: false)
  |> aggregateWindow(every: 1m, fn: mean, createEmpty: true)
  |> fill(usePrevious: true)
  |> fill(value: 0.0)
  |> group(columns: ["type"])
  |> aggregateWindow(every: 1m, fn: sum, createEmpty: false)
  |> yield(name: "population")
  1. 我首先使用last来获得每个窗口的最新状态(尽管last实际上删除了空表,因此使createEmpty: true无论如何都没用)
  2. 然后对于没有任何点的窗口,我将meancreateEmpty: true ,以便为空窗口创建具有 null _value点。 对于那些确实有实际点的窗口, mean不应更改值应该只有每个窗口1点,因为我们用last前面。 这里使用mean目的只是为空窗口创建空点。 这里的步骤只是找到一个不做任何事情的函数,它不会删除由createEmpty创建的空表。 仅供参考,我尝试了许多函数,包括创建我自己的自定义函数,如reducemap但它们确实删除了空表(甚至不允许分配 null),我什至创建了一个空函数,如fn: (tables=<-, x) => tables用于aggregateWindow窗口的fn: (tables=<-, x) => tables ,但它无论如何都会删除空表。 所以mean是我最好的选择,尽管副作用是我的值从 int 变为 float。
  3. 我在这里使用fill来用最后一个窗口的值替换空点。 这就是为什么我试图将 null 分配给最后一步中空窗口中的点,而mean只能这样做。 第二次fill用于那些应该代表 0 状态的早期空窗口。
  4. 然后按类型groupsum它们应该是我寻找的结果

希望以后能帮助到和我一样情况的人

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM