文档文档

使用数学运算转换数据

Flux,InfluxData 的数据脚本和查询语言,支持数据转换中的数学表达式。本文介绍如何使用 Flux 算术运算符 “映射” 数据并使用数学运算转换值。

如果您刚开始使用 Flux 查询,请查看以下内容

  • Flux 入门,了解 Flux 和 Flux 查询部分的概念概述。
  • 执行查询,了解运行查询的各种方法。
基本数学运算
// Examples executed using the Flux REPL
> 9 + 9
18
> 22 - 14
8
> 6 * 5
30
> 21 / 7
3

请参阅 Flux 读取-求值-打印循环 (REPL)

操作数必须是相同类型

Flux 数学运算中的操作数必须是相同的数据类型。例如,整数不能与浮点数一起用于运算。否则,您将收到类似于以下的错误

Error: type error: float != int

要将操作数转换为相同类型,请使用 类型转换函数 或手动格式化操作数。操作数数据类型决定输出数据类型。例如

100 // Parsed as an integer
100.0 // Parsed as a float

// Example evaluations
> 20 / 8
2

> 20.0 / 8.0
2.5

自定义数学函数

Flux 允许您 创建使用数学运算的自定义函数。查看以下示例。

自定义乘法函数
multiply = (x, y) => x * y

multiply(x: 10, y: 12)
// Returns 120
自定义百分比函数
percent = (sample, total) => (sample / total) * 100.0

percent(sample: 20.0, total: 80.0)
// Returns 25.0

转换数据流中的值

要转换输入流中的多个值,您的函数需要

下面的 multiplyByX() 函数示例包括

  • 一个 tables 参数,表示输入数据流 (<-)。
  • 一个 x 参数,它是 _value 列中的值所乘的数字。
  • 一个 map() 函数,它迭代输入流中的每一行。它使用 with 运算符来保留每一行中的现有列。它还将 _value 列乘以 x
multiplyByX = (x, tables=<-) => tables
    |> map(fn: (r) => ({r with _value: r._value * x}))

data
    |> multiplyByX(x: 10)

示例

将字节转换为千兆字节

要将活动内存从字节转换为千兆字节 (GB),请将 mem 测量中的 active 字段除以 1,073,741,824。

map() 函数迭代管道传递数据中的每一行,并通过将原始 _value 除以 1073741824 来定义新的 _value

from(bucket: "example-bucket")
    |> range(start: -10m)
    |> filter(fn: (r) => r._measurement == "mem" and r._field == "active")
    |> map(fn: (r) => ({r with _value: r._value / 1073741824}))

您可以将相同的计算转换为函数

bytesToGB = (tables=<-) => tables
    |> map(fn: (r) => ({r with _value: r._value / 1073741824}))

data
    |> bytesToGB()

包含部分千兆字节

由于原始指标(字节)是整数,因此运算的输出是整数,不包含部分 GB。要计算部分 GB,请使用 float() 函数_value 列及其值转换为浮点数,并将除法运算中的分母格式化为浮点数。

bytesToGB = (tables=<-) => tables
    |> map(fn: (r) => ({r with _value: float(v: r._value) / 1073741824.0}))

计算百分比

要计算百分比,请使用简单的除法,然后将结果乘以 100。

> 1.0 / 4.0 * 100.0
25.0

有关计算百分比的深入了解,请参阅 计算百分比

透视 vs 连接

要在 Flux 中查询和使用数学运算中的值,操作数值必须存在于单行中。pivot()join() 都可以做到这一点,但两者之间存在重要的差异

透视性能更高

pivot() 读取和操作单个数据流。join() 需要两个数据流,并且读取和组合两个数据流的开销可能很大,特别是对于较大的数据集。

对于多个数据源,使用连接

从不同的存储桶或数据源查询数据时,使用 join()

将字段透视为列以进行数学计算
data
    |> pivot(rowKey: ["_time"], columnKey: ["_field"], valueColumn: "_value")
    |> map(fn: (r) => ({r with _value: (r.field1 + r.field2) / r.field3 * 100.0}))
连接多个数据源以进行数学计算
import "sql"
import "influxdata/influxdb/secrets"

pgUser = secrets.get(key: "POSTGRES_USER")
pgPass = secrets.get(key: "POSTGRES_PASSWORD")
pgHost = secrets.get(key: "POSTGRES_HOST")

t1 = sql.from(
    driverName: "postgres",
    dataSourceName: "postgresql://${pgUser}:${pgPass}@${pgHost}",
    query: "SELECT id, name, available FROM example_table",
)

t2 = from(bucket: "example-bucket")
    |> range(start: -1h)
    |> filter(fn: (r) => r._measurement == "example-measurement" and r._field == "example-field")

join(tables: {t1: t1, t2: t2}, on: ["id"])
    |> map(fn: (r) => ({r with _value: r._value_t2 / r.available_t1 * 100.0}))

此页是否对您有帮助?

感谢您的反馈!


Flux 的未来

Flux 即将进入维护模式。您可以继续像现在一样使用它,而无需对代码进行任何更改。

阅读更多

现已全面上市

InfluxDB 3 Core 和 Enterprise

快速启动。更快扩展。

获取更新

InfluxDB 3 Core 是一个开源、高速、最近数据引擎,可实时收集和处理数据,并将其持久化到本地磁盘或对象存储。InfluxDB 3 Enterprise 以 Core 的基础为构建,增加了高可用性、读取副本、增强的安全性以及数据压缩,以实现更快的查询和优化的存储。InfluxDB 3 Enterprise 的免费层可供非商业家庭或业余爱好者使用。

有关更多信息,请查看