你当前正在访问 Microsoft Azure Global Edition 技术文档网站。 如果需要访问由世纪互联运营的 Microsoft Azure 中国技术文档网站,请访问 https://docs.azure.cn

使用数据流转换来转换数据

重要说明

本页包含有关使用 Kubernetes 部署清单文件(预览版)管理 Azure IoT 操作组件的说明。 此功能具有几个限制,不应用于生产工作负荷。

有关 beta 版本、预览版或尚未正式发布的版本的 Azure 功能所适用的法律条款,请参阅 Microsoft Azure 预览版的补充使用条款

使用数据流转换,可以在 Azure IoT 操作中转换数据。 数据流中的 conversion 元素用于计算输出字段的值。 可以在数据流转换中使用输入字段、可用操作、数据类型和类型转换。

数据流 conversion 元素用于计算输出字段的值:

inputs: [
  '*.Max' // - $1
  '*.Min' // - $2
]
output: 'ColorProperties.*'
expression: '($1 + $2) / 2'

关于转换,有几个方面需要了解:

  • 引用输入字段:如何在转换公式中引用输入字段中的值。
  • 可用操作:可在转换中利用的操作。 例如,加法、减法、乘法、除法。
  • 数据类型:公式可以处理和操作的数据类型。 例如整数、浮点和字符串。
  • 类型转换:如何在输入字段值、公式计算和输出字段之间转换数据类型。

输入字段

在转换中,公式可以对静态值(如 25)或从输入字段派生的参数进行操作。 映射定义公式可以访问的这些输入字段。 每个字段根据其在输入列表中的顺序进行引用:

inputs: [
  '*.Max'      // - $1
  '*.Min'      // - $2
  '*.Mid.Avg'  // - $3
  '*.Mid.Mean' // - $4
]
output: 'ColorProperties.*'
expression: '($1, $2, $3, $4)'

在本例中,转换的结果是一个包含 [Max, Min, Mid.Avg, Mid.Mean] 值的数组。 YAML 文件(# - $1# - $2)中的注释是可选的;但它们有助于阐明每个字段属性及其在转换公式中的作用之间的联系。

数据类型

不同的序列化格式支持各种数据类型。 例如,JSON 提供了以下几个基元类型:字符串、数字、布尔和 null。 还包括这些基元类型的数组。

当映射器读取输入属性时,它会将其转换为内部类型。 这种转换对于将数据保存在内存中直到将其写入输出字段是必要的。 无论输入和输出序列化格式是否相同,都会转换为内部类型。

内部表示形式采用以下数据类型:

类型 说明
bool 逻辑 true/false。
integer 存储为 128 位带符号整数。
float 存储为 64 位浮点数。
string UTF-8 字符串。
bytes 二进制数据,由 8 位无符号值组成的字符串。
datetime UTC 或本地时间,分辨率为纳秒。
time 一天中的时间,分辨率为纳秒。
duration 持续时间,分辨率为纳秒。
array 前面列出的任何类型的数组。
map 前面列出的任何类型的(键、值)对的向量。

输入记录字段

当读取输入记录字段时,其基础类型将转换为这些内部类型变体之一。 内部表示形式具有足够的通用性,可以处理大多数输入类型,只需要很少的转换或不需要转换。

对于某些格式,使用代理项类型。 例如,JSON 没有 datetime 类型,,而是将 datetime 值存储为根据 ISO8601 格式化的字符串。 当映射器读取此类字段时,内部表示形式仍为字符串。

输出记录字段

映射器采用灵活设计,可以将内部类型转换为输出类型,以适应数据来自具有有限类型系统的序列化格式的场景。 以下示例演示如何处理转换:

  • 数值类型:这些类型可以转换为其他表示形式,但可能会伴随一定程度的精度丢失。 例如,64 位浮点数 (f64) 可以转换为 32 位整数 (i32)。
  • 字符串转换为数字:如果传入记录包含类似 123 的字符串,并且输出字段是 32 位整数,则映射器将值转换为数字并写入。
  • 字符串转换为其他类型
    • 如果输出字段为 datetime,则映射器将尝试将字符串解析为 ISO8601 格式的 datetime
    • 如果输出字段为 binary/bytes,则映射器会尝试将字符串从 base64 编码的字符串反序列化。
  • 布尔值:
    • 如果输出字段是数值,则转换为 0/1
    • 如果输出字段是字符串,则转换为 true/false

对类型使用转换公式

在映射中,可选公式可以指定在将数据写入输出字段之前如何处理来自输入的数据。 如果未指定公式,映射器将使用内部类型和转换规则将输入字段复制到输出。

如果指定了公式,则公式中可用的数据类型仅限于:

  • 整数
  • 浮点数字
  • 字符串
  • 布尔型
  • 上述类型的数组
  • 缺失值

Mapbyte 不能参与公式计算。

与时间相关的类型(datetimetimeduration)被转换为表示时间(以秒为单位)的整数值。 公式求值后,结果存储在内部表示形式中,而不会转换回原始类型。 例如,转换为秒的 datetime 仍是一个整数。 如果该值将用于 datetime 字段,则必须应用显式转换方法。 例如,将值转换为 ISO8601 格式的字符串,该字符串会自动转换为输出序列化格式的 datetime 类型。

使用不规则类型

数组和缺失值等类型需遵循特殊注意事项。

数组

可以通过使用聚合函数从多个元素中计算单个值来处理数组。 例如,通过使用输入记录:

{
  "Measurements": [2.34, 12.3, 32.4]
}

使用映射:

inputs: [
  'Measurements' // - $1
]
output: 'Measurement'
expression: 'min($1)'

此配置从 Measurements 数组中为输出字段选择最小值。

数组也可以从多个单个值创建:

inputs: [
  'minimum' // - - $1
  'maximum' // - - $2
  'average' // - - $3
  'mean'    // - - $4
]
output: 'stats'
expression: '($1, $2, $3, $4)'

此映射创建一个包含最小值、最大值、平均值和均值的数组。

缺失值

“缺失值”是一种在场景中使用的特殊类型,例如:

  • 通过提供替代值来处理输入中缺失的字段。
  • 根据字段的存在情况有条件地移除字段。

使用缺失值的示例映射:

{
  "Employment": {      
    "Position": "Analyst",
    "BaseSalary": 75000,
    "WorkingHours": "Regular"
  }
}

输入记录包含 BaseSalary 字段,但这可能是可选的。 如果字段缺失,则必须从上下文化数据集中添加一个值:

{
  "Position": "Analyst",
  "BaseSalary": 70000,
  "WorkingHours": "Regular"
}

映射可以检查字段是否出现在输入记录中。 如果找到该字段,则输出将接收该现有值。 否则,输出将从上下文数据集中接收值。 例如:

inputs: [
  'BaseSalary' // - - - - - - - - - - - $1
  '$context(position).BaseSalary' //  - $2
]
output: 'BaseSalary'
expression: 'if($1 == (), $2, $1)'

conversion 使用 if 函数,该函数有三个参数:

  • 第一个参数是条件。 在示例中,它检查输入字段(别名为 $1)的 BaseSalary 字段是否为缺失值。
  • 如果第一个参数中的条件为 true,则第二个参数是函数的结果。 在本例中,它是上下文化数据集(别名为 $2)的 BaseSalary 字段。
  • 如果第一个参数为 false,则第三个参数是条件的值。

可用函数

数据流提供了一组内置函数,可在转换公式中使用。 可使用这些函数执行常见运算,例如算术、比较和字符串操作。 可用函数包括:

函数 说明 示例
min 返回数组中的最小值。 min(2, 3, 1) 返回 1min($1) 返回数组 $1 中的最小值
max 返回数组中的最大值。 max(2, 3, 1) 返回 3max($1) 返回数组 $1 中的最大值
if 根据条件返回值。 如果 $1 大于 10,则 if($1 > 10, 'High', 'Low') 返回 'High';否则返回 'Low'
len 返回字符串的字符长度或元组中的元素数量。 len("Azure") 返回 5len(1, 2, 3) 返回 3len($1) 返回数组 $1 中的元素数量
floor 返回小于或等于某个数字的最大整数。 floor(2.9) 返回 2
round 返回与数字最接近的整数,将 0.0 舍入一半。 round(2.5) 返回 3
ceil 返回大于或等于数字的最小整数。 ceil(2.1) 返回 3
scale 将值从一个范围缩放到另一个范围。 scale($1, 0, 10, 0, 100) 将输入值从 0 到 10 的范围缩放到 0 到 100 的范围

转换函数

数据流提供了多个内置转换函数,用于常见单位转换,例如温度、压力、长度、重量和体积。 下面是一些示例:

转换 公式 函数名称
摄氏度到华氏度 F = (C * 9/5) + 32 cToF
PSI 转换为 Bar Bar = PSI * 0.0689476 psiToBar
英寸转换为厘米 厘米 = 英寸 * 2.54 inToCm
英尺转换为米 米 = 英尺 * 0.3048 ftToM
Lbs 转换为 kg Kg = lbs * 0.453592 lbToKg
加仑转换为升 升 = 加仑 * 3.78541 galToL

也支持反向转换:

转换 公式 函数名称
华氏度转换为摄氏度 C = (F - 32) * 5/9 fToC
Bar 转换为 PSI PSI = bar / 0.0689476 barToPsi
厘米转换为英寸 英寸 = 厘米/ 2.54 cmToIn
米转换为英尺 英尺 = 米 / 0.3048 mToFt
Kg 转换为 lbs Lbs = kg / 0.453592 kgToLb
升转换为加仑 加仑 = 升 / 3.78541 lToGal

此外,你还可以使用基本数学公式定义自己的转换函数。 系统支持加法 (+)、减法 (-)、乘法 (*) 和除法 (/) 等运算符。 这些运算符遵循标准的优先级规则,可以使用括号进行调整,以确保正确的运算顺序。 这样,你就可以自定义单位转换,以满足特定需求。

按优先级列出的可用运算符

操作员 说明
^ 求幂:$1 ^ 3

由于 Exponentiation 具有最高优先级,因此它会首先执行;除非括号覆盖此顺序:

  • $1 * 2 ^ 3 被解释为 $1 * 8,因为 2 ^ 3 部分在乘法之前首先执行。
  • ($1 * 2) ^ 3 在求幂之前处理乘法。
操作员 说明
- 否定
! 逻辑“非”

NegationLogical not 具有高优先级,因此它们总是坚持使用它们的近邻,除非涉及求幂:

  • -$1 * 2 先对 $1 取反,然后相乘。
  • -($1 * 2) 将结果相乘,然后取反。
操作员 说明
* 乘法:$1 * 10
/ 除法:$1 / 25(如果两个参数均为整数,则结果为整数;否则为浮点数)
% 取模:$1 % 25

MultiplicationDivisionModulo 具有相同的优先级,从左到右执行,除非括号改变了顺序。

操作员 说明
+ 对数值使用加法,对字符串使用串联
-

与上一组中的运算相比,AdditionSubtraction 被视为优先顺序较低的运算:

  • $1 + 2 * 3 结果为 $1 + 6,因为 multiplication 的优先级更高,所以先执行 2 * 3
  • ($1 + 2) * 3Addition 优先于 Multiplication
操作员 说明
< 小于
> 大于
<= 小于或等于
>= 大于或等于
== 等于
!= 不等于

Comparisons 对数值、布尔和字符串值进行操作。 由于它们的优先级低于算术运算符,因此不需要括号来有效地比较结果:

  • $1 * 2 <= $2 等同于 ($1 * 2) <= $2
操作员 说明
|| 逻辑或
&& 逻辑与

逻辑运算符用于链接以下条件:

  • $1 > 100 && $2 > 200