你当前正在访问 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 时函数的结果。 在本例中,它是上下文化数据集的 BaseSalary 字段(别名为 $2)。
  • 第三个参数是第一个参数为 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
英寸 (Inch) 转换为厘米 (CM) CM = Inch * 2.54 inToCm
英尺 (Foot) 转换为米 (Meter) Meter = Foot * 0.3048 ftToM
磅 (Lbs) 转换为千克 (KG) KG = Lbs * 0.453592 lbToKg
加仑 (Gallons) 转换为升 (Liters) Liters = Gallons * 3.78541 galToL

也支持反向转换:

转换 公式 函数名
华氏度到摄氏度 C = (F - 32) * 5/9 fToC
巴 (Bar) 到 PSI PSI = Bar / 0.0689476 barToPsi
厘米 (CM) 转换为英寸 (Inch) Inch = CM / 2.54 cmToIn
米 (Meter) 转换为英尺 (Foot) Foot = Meter / 0.3048 mToFt
千克 (KG) 转换为磅 (Lbs) Lbs = KG / 0.453592 kgToLb
升 (Liters) 转换为加仑 (Gallons) Gallons = Liters / 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) * 3,将先执行 Addition,然后执行 Multiplication
运算符 说明
< 小于
> 大于
<= 小于或等于
>= 大于或等于
== 等于
!= 不等于

可以对数值、布尔值和字符串值执行 Comparisons 运算。 由于它们的优先顺序低于算术运算符,因此无需括号即可有效地比较结果:

  • $1 * 2 <= $2 等效于 ($1 * 2) <= $2
运算符 说明
|| 逻辑或
&& 逻辑与

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

  • $1 > 100 && $2 > 200