当在 Flux 中使用 from()
查询 InfluxDB 数据返回的数据为包含零或多个表的流数据,官方原文为 stream of tables (很多地方翻译为“表流”)。
当这个表流里为多个表的时候,有些情况我们是需要把多个表合并为一个表后才能进行对应的操作。如:使用 sort()
进行排查,这个操作是对表流中的每个表中的数据进行排序,而不是对表流中所有数据进行排序。这时就需要把表流中的多个表中的数据合并为一个表后再使用 sort() 排序。
那么如何将表流中的多个表合并到一个表中能。经过翻看大量的官方文档,找到了下面两种方法。
在这之前需要使用 Telegraf 采集某个计算机中的 cpu 和 内存的数据并保存到 InfluxDB 中的名为 telegraf 的 bucket 中,以便后面供 Flux 使用。 cpu 数据保存到 名为 cpu 的 _measurement 中,内存数据保存到名为 mem 的 _measurement中(使用 Telegraf 的 # Memory Input Plugin 和 # # CPU Input Plugin 的默认配置即可)。
方法1:使用 group()
合并多个表
这有个需要注意的地方就是 _value
的类型,因为表流里返回的多个表中 _value
的值类型可能不一样,比如:使用 Telegraf 采集内存的数据中, available 为 long 类型,而 available_percent 为 double 类型。
就会出现下面这个错误提示:
schema collision: cannot group integer and float types together
示例代码,如下:
from(bucket: "telegraf")
|> range(start: -60s)
|> filter(fn: (r) => r._measurement == "mem")
|> group()
方法2:使用 window(every: inf)
合并多个表
这个也不是很完美,可能也会有方法1中的那个问题。
另一个导致不能合并的原因是因为有可用于分组的字段中的值不同。
必须有 _time 列,不然会出现下面错误:
runtime error @20:14-20:32: window: missing time column "_time"
下面代码中删除了两个 _field 和 cpu 两个可用于分组的列。但,还有个 _measurement 列,这个列中当前有两个 cpu 和 mem 两类数据。所以,
示例代码,如下:
from(bucket: "telegraf")
|> range(start: -20s)
|> filter(fn: (r) => r._field == "usage_idle" or r._field == "available_percent")
|> drop(columns: ["_field", "cpu"])
|> window(every: inf)
参考资料: