文档文档

使用动态类型

动态类型是运行时类型未知的数据的包装器。当处理来自外部源(如 JSON)的数据时,动态类型会有所帮助,这些外部源支持没有等效 Flux 类型的数据类型。

表不支持动态类型

Flux 表格不支持动态类型。 要在 Flux 表格中包含动态值,您必须将动态类型转换为 Flux 基本类型。有关将动态类型转换为基本类型并将其包含在表格中的完整示例,请参阅在表格中包含动态类型

将 JSON 解析为 Flux 类型

动态类型的主要(但非唯一)用例是将 JSON 数据转换为原生 Flux 类型;特别是 Flux 数组记录

由于 Flux 中严格的类型规则,JSON 数据并非总是能顺利解析为原生 Flux 类型。最常见的原因是 Flux 数组要求所有子元素都为相同类型。JSON 数组允许元素具有不同的类型。

对于 Flux 记录(JSON 对象的推论),记录中的属性是记录类型的一部分。如果您有一个 JSON 对象数组,其中对象的模式不同,则该数组无法解析为 Flux 数组,因为数组中记录的类型不匹配。

查看无法直接解析为 Flux 数组的 JSON 数组示例

动态类型提供了一种解决 JSON 和 Flux 类型之间差异的方法。

动态类型语法

Flux 没有为动态类型提供字面量语法。要将值强制转换为动态类型,请执行以下操作

  1. 导入experimental/dynamic
  2. 使用dynamic.dynamic() 将值转换为动态类型。
import "experimental/dynamic"

dynamic.dynamic(v: "Example string")

// Returns dynamic(Example string)

引用动态类型中的值

使用方括号和点表示法来引用动态记录和数组中的值。使用 exists 运算符检查动态类型是否包含非空值。

引用动态记录中的值

import "experimental/dynamic"

record = {one: 1, two: 2, three: 3}
dynamicRecord = dynamic.dynamic(v: record)

dynamicRecord.one
// Returns dynamic(1)

dynamicRecord["two"]
// Returns dynamic(2)

引用动态数组中的值

import "experimental/dynamic"

arr = ["a", "b", "c"]
dynamicArr = dynamic.asArray(v: dynamic.dynamic(v: arr))

dynamicArr[0]
// Returns dynamic(a)

确保动态类型包含非空值

使用 exists 运算符检查动态类型是否包含非空值。如果您尝试访问空动态类型的成员,Flux 将返回错误。exists 可让您防止因尝试访问空动态类型中的成员而导致的错误。

查看使用 exists 检查非空动态类型的示例

对动态类型进行操作

将动态类型转换为 Flux 类型

基本类型

使用string() 将动态类型转换为字符串。string() 返回动态值的字符串表示形式。

import "experimental/dynamic"

dynamicValue = dynamic.dynamic(v: "string")

string(v: dynamicValue)
// Returns "string"

使用int() 将动态类型转换为整数。int() 返回动态值的整数等效值

import "experimental/dynamic"

dynamicValue = dynamic.dynamic(v: "12")

int(v: dynamicValue)
// Returns 12

使用uint() 将动态类型转换为无符号整数(UInteger)。uint() 返回动态值的UInteger 等效值

import "experimental/dynamic"

dynamicValue = dynamic.dynamic(v: "12")

uint(v: dynamicValue)
// Returns 12

使用float() 将动态类型转换为浮点值。float() 返回动态值的浮点等效值

import "experimental/dynamic"

dynamicValue = dynamic.dynamic(v: "12.1")

float(v: dynamicValue)
// Returns 12.1

使用bool() 将动态类型转换为布尔值。bool() 返回动态值的布尔等效值

import "experimental/dynamic"

dynamicValue = dynamic.dynamic(v: "true")

bool(v: dynamicValue)
// Returns true

使用duration() 将动态类型转换为持续时间值。duration() 返回动态值的持续时间等效值

import "experimental/dynamic"

dynamicValue = dynamic.dynamic(v: 3000000000)

duration(v: dynamicValue)
// Returns 3s

使用time() 将动态类型转换为时间值。time() 返回动态值的时间等效值

import "experimental/dynamic"

dynamicValue = dynamic.dynamic(v: 1640995200000000000)

time(v: dynamicValue)
// Returns 2022-01-01T00:00:00.000000000Z

使用bytes() 将动态类型转换为字节编码的字符串。bytes() 返回动态值的字节等效值

import "experimental/dynamic"

dynamicValue = dynamic.dynamic(v: "Hello world!")

bytes(v: dynamicValue)
// Returns 0x48656c6c6f20776f726c6421
  1. 使用string() 将动态类型转换为字符串。
  2. 导入regexp并使用regexp.compile() 将字符串值转换为正则表达式类型。
import "experimental/dynamic"
import "regexp"

dynamicValue = dynamic.dynamic(v: "^[abc][123]{1,}")
stringValue = string(v: dynamicValue)

regexp.compile(v: stringValue)
// Returns /^[abc][123]{1,}/

复合类型

动态复合类型几乎总是来自处理字节编码的 JSON 字符串。以下所有示例均假设如此。

要将 JSON 数组转换为 Flux 数组

  1. 导入以下包

  2. 使用dynamic.jsonParse() 将字节编码的 JSON 字符串解析为动态类型。

  3. 使用dynamic.asArray() 将动态类型的数组转换为动态类型数组。

  4. 使用array.map() 迭代数组中的每个元素,并显式地将动态类型转换为基本类型

查看包含标量值数组的示例

查看包含 JSON 对象数组的示例

要将 JSON 对象转换为 Flux 记录

  1. 导入experimental/dynamic
  2. 使用dynamic.jsonParse() 将字节编码的 JSON 字符串解析为动态类型。
  3. 定义一个新的记录,并将动态类型的每个属性转换为基本类型
JSON 对象
{"first-name": "John", "last-name": "Doe", "age": 42}
将 JSON 对象转换为 Flux 记录
import "experimental/dynamic"

json = jsonBytes // Byte-encoded JSON above
parsed = dynamic.jsonParse(data: json)

newRecord = {
    fname: string(v: parsed["first-name"]),
    lname: string(v: parsed["last-name"]),
    age: int(v: parsed.age)
}

// newRecord returns {age: 42, fname: John, lname: Doe}

检查动态类型内部值的类型

使用dynamic.isType() 检查动态类型内部值的类型。

以下示例使用http/requestsFruityvice API 返回有关苹果的 JSON 对象信息。

查看返回的 JSON 对象

import "experimental/dynamic"

response = requests.get(url: "https://www.fruityvice.com/api/fruit/apple")
parsed = dynamic.jsonParse(data: response.body)

dynamic.isType(v: parsed.genus, type: "string")
// Returns true

dynamic.isType(v: parsed.nutritions, type: "array")
// Returns false

dynamic.isType(v: parsed.nutritions, type: "object")
// Returns true

在表格中包含动态类型

Flux 表格不支持动态类型。 要在 Flux 表格中包含动态值,请将动态类型转换为 Flux 基本类型

以下示例使用array.from() 构建使用动态类型的临时表格。定义行记录时,每个动态类型都必须转换为 Flux 基本类型。

import "array"
import "experimental/dynamic"

dynamicString = dynamic.dynamic(v: "one")
dynamicInt = dynamic.dynamic(v: 1)
dynamicFloat = dynamic.dynamic(v: 1.0)
dynamicBool = dynamic.dynamic(v: true)

array.from(
    rows: [
        {
            string: string(v: dynamicString),
            int: int(v: dynamicInt),
            float: float(v: dynamicFloat),
            bool: bool(v: dynamicBool),
        },
    ],
)

查看输出表格

将 JSON 数组转换为 Flux 表格

  1. 导入以下包

  2. 使用dynamic.jsonParse() 将从 requests.get() 返回的 JSON 响应正文解析为 Flux 动态类型。定义一个变量以捕获已解析的 JSON。以下示例使用 parsed 变量。

  3. 使用dynamic.asArray()dynamic.jsonParse() 返回的动态类型转换为动态数组。定义一个变量以捕获动态数组。以下示例使用 fruit 变量。

  4. 使用array.map() 执行以下操作

以下示例使用http/requestsFruityvice API 返回有关各种水果的 JSON 信息,然后将返回的数据结构化为 Flux 表格。

import "array"
import "experimental/dynamic"
import "http/requests"

response = requests.get(url: "https://www.fruityvice.com/api/fruit/all")
parsed = dynamic.jsonParse(data: response.body)
fruit = dynamic.asArray(v: parsed)

fruit_flat =
    fruit
        |> array.map(
            fn: (x) =>
                ({
                    name: string(v: x.name),
                    cals: int(v: x.nutritions.calories),
                    carbs: float(v: x.nutritions.carbohydrates),
                    fat: float(v: x.nutritions.fat),
                    protein: float(v: x.nutritions.protein),
                    sugar: float(v: x.nutritions.sugar),
                }),
        )

array.from(rows: fruit_flat)

查看输出表格

将动态类型编码为 JSON

将动态记录编码为 JSON

  1. 导入 experimental/dynamic 包。
  2. 使用dynamic.dynamic() 将记录转换为动态类型。
  3. 使用dynamic.jsonEncode() 将动态记录转换为字节编码的 JSON 字符串。
import "experimental/dynamic"

dynamicRecord = dynamic.dynamic(v: {one: 1, two: 2, three: 3})

dynamic.jsonEncode(v: dynamicRecord)

// Returns the following byte-encoded JSON string:
// {"one":1,"three":3,"two":2}

将不同基本类型的动态数组编码为 JSON

构建一个动态数组,其中每个元素都是不同的基本类型。如果您要将 JSON 数据发送到期望值数组(其中每个值都是不同类型)的 API,则这可能是必要的。Flux 数组中的值必须是相同的类型,因此您必须构建动态类型的动态数组

  1. 导入 experimental/dynamic 包。
  2. 使用dynamic.dynamic()
    将数组转换为动态类型。
  3. 使用 dynamic.dynamic() 将数组中的所有值转换为动态类型。
  4. 使用dynamic.jsonEncode() 将动态数组转换为字节编码的 JSON 字符串。
import "experimental/dynamic"

arr =
    dynamic.dynamic(
        v: [
            dynamic.dynamic(v: "three"),
            dynamic.dynamic(v: 2),
            dynamic.dynamic(v: true)
        ],
    )

dynamic.jsonEncode(v: arr)

// Returns the following byte-encoded JSON string:
// ["three", 2, true]

此页内容对您有帮助吗?

感谢您的反馈!


Flux 的未来

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

阅读更多

现已全面上市

InfluxDB 3 Core 和 Enterprise

快速启动。更快扩展。

获取更新

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

有关更多信息,请查看