如何通过InfluxQL查询InfluxDB去重值对应的真实时间戳
InfluxDB查询语义版本去重并保留有效时间戳方案
distinct() 是InfluxQL的聚合类函数,本身设计上不会关联去重值对应的原始采样时间,未指定分组逻辑时默认返回epoch 0(1970-01-01T00:00:00Z)作为聚合结果时间,要拿到每个版本对应的有效时间戳,可以用以下两种查询方式实现:
方案1:获取每个版本首次/末次上报时间(InfluxQL原生支持,兼容1.x/2.x版本)
通过GROUP BY对版本字段分组,配合选择类聚合函数提取对应时间,不需要额外依赖Flux语法:
- 取每个版本首次被采集到的时间戳,查询语句如下:
SELECT FIRST("firmware_version") AS "firmware_version" FROM "app" WHERE ("host" =~ /^something$/) GROUP BY "firmware_version"
- 如果需要取每个版本最后一次上报的时间戳,把语句里的
FIRST()替换为LAST()即可。
返回结果会直接携带每个版本对应的有效时间,不会出现时间戳为0的问题,结果示例:
name: app tags: firmware_version=5.8.19 time firmware_version ---- ---------------- 1651658809605790508 5.8.19 name: app tags: firmware_version=5.10.1 time firmware_version ---- ---------------- 1656723419201780000 5.10.1 name: app tags: firmware_version=5.11.0 time firmware_version ---- ---------------- 1661298765123400000 5.11.0
方案2:获取所有版本变更节点时间(适合做版本切换时序展示)
如果需要过滤掉同版本重复上报的冗余数据,只保留版本发生变化的时间点,InfluxDB 2.x及以上版本可以用Flux查询实现:
from(bucket: "对应存储桶名称") |> range(start: v.timeRangeStart, stop: v.timeRangeStop) |> filter(fn: (r) => r._measurement == "app" and r.host =~ /^something$/) |> filter(fn: (r) => r._field == "firmware_version") // 相邻点对比,过滤同版本重复上报数据 |> duplicate(column: "_value", as: "last_version") |> shift(columns: ["last_version"], shift: 1n) |> filter(fn: (r) => r._value != r.last_version or not exists r.last_version) |> keep(columns: ["_time", "_value"])
Grafana展示补充
不需要强制把字符串类型的语义版本转换为数值类型就能做时序展示:
- 表格视图直接使用上述查询结果即可,自带版本与对应时间戳字段
- 时序类展示直接选用「状态时间线(State timeline)」面板,将版本字符串作为状态值、时间作为X轴,就能直观展示每个版本的生效时间段。
内容的提问来源于stack exchange,提问作者lnksz
相关产品推荐
相关产品推荐

