数据查询语法和函数
JSON格式消息处理
规则引擎采用一套平台定义的查询语法对原始数据进行格式转换和过滤,用户通过编写查询语句和过滤条件可将符合条件的数据转化为期望的目标格式后流转到其他云产品或服务进行进一步业务处理。
语法特点
- 允许以紧凑且直观的符号表示复杂的查询。
- 提供丰富的内置运算符和函数来处理和组合提取的数据。
- 可以使用熟悉的JSON对象和数组语法将查询结果格式化为任何JSON输出结构。
- 结合函数,可以构建高级表达式来处理JSON查询和转换任务。
支持查询语法和函数的功能点
- 查询语句
将原始消息中选择的数据、规则引擎预置函数返回数据、常量赋值给新的key并组装为需要输出的json格式对象。
- 过滤条件
从原始消息中过滤指定条件的数据,使用查询语法或预置函数编写一个可以输出布尔值的表达式。
语法示例
示例消息
除非另有说明,否则示例均使用以下JSON文档样本:
{
"reqId":"442c1da4-9d3a-4f9b-a6e9-bfe858e4ac43",
"method":"thing.event.post",
"timestamp":1465376157007,
"deviceName":"device001",
"productName":"product001",
"params":{
"host":"192.166.1.1",
"color":"red",
"historydDatas":[
{
"key":"temperature",
"value":50,
"time":1465376157007
},
{
"key":"humidity",
"value":80,
"time":1465376157337
},
{
"key":"pressure",
"value":8.5,
"time":1465376157337
},
{
"key":"speed",
"value":80,
"time":1465376157337
}
]
},
"properties":{
"temperature":35,
"humidity":22
},
"other":{
"Misc":null
}
}
过滤条件
以下是一个简单的过滤条件逻辑表达式,可以在规则编辑调试页面作为测试熟悉语法的使用
示例语句的含义是:
过滤原始消息中properties下temperature值大于20且humidity小于30 的消息,转发到规则的数据目的地
properties.temperature>20 and properties.humidity<30
返回结果
true
表达式将返回一个布尔值,如果为true则继续进行格式转换并转发到数据目的地,返回为false时则该消息不会被继续转换和流转
格式转化
以下是一个简单的查询语句示例,帮助开发者快速入门,可以在规则编辑调试页面作为测试熟悉语法的使用
示例语句的含义是:
- 将原始消息中key为 productName 的元素value赋值给目标对象的 device.product
- 将原始消息中key为 deviceName 的元素value赋值给目标对象的 device.deviceName
- 将原始消息中key为 timestamp 的元素value赋值给目标对象的 time
{
"device":{
"product":productName,
"device":deviceName
},
"time":timestamp
}
最终输出结果:
{
"device":{
"product":"product001",
"device":"device001"
},
"time":1465376157007
}
操作符
规则引擎查询语法支持以下操作符,可以在查询语句和过滤条件中使用操作符构建简单表达式。
操作符 | 功能描述 | 示例 |
---|---|---|
. | 取值路径操作符 | params.host $.deviceName |
+ | 加 | 1+2a+b |
- | 减 | a-b |
* | 乘 | a*b |
/ | 除 | a/b |
% | 取模 | a%b |
= | 等于 | a=b |
!= | 不等于 | != |
> | 大于 | a>b |
< | 小于 | a<b |
>= | 大于等于 | a>=b |
<= | 小于等于 | a<=b |
in | 包含 | a in b |
and | 与 | a and b |
or | 或 | a or b |
& | 字符串连接 | a&b&"c" |
() | 优先运算符 | (a+b)*c |
常用语法
获取完整原始消息
使用$符号可以获得完整的原始消息。
查询语句 | 结果消息 | 描述说明 |
---|---|---|
$ | 原始消息 | 返回不经任何转换的原始对象在查询语句中直接输入$作为查询语句规则将不对消息进行格式转换,会将消息原文转发到数据目的地 |
$.productName | "product001" | 返回原始消息中指定key的值如果是原始消息的第一层key,可以省略$符号直接使用productName获得,即此时$.productName等价于productName |
查询JSON对象
“.”分隔的字段名称,可定位到任意深度嵌套的JSON对象结构中的。
- 表达式返回定位到位置路径中的最后一步后引用的JSON值。
- 如果在定位路径的导航期间未找到字段,则该表达式不返回任何内容(返回undefined)。
- 由于输入文档中不存在数据,不会引发任何错误。
查询语句 | 结果消息 | 描述说明 |
---|---|---|
$.productName | "product001" | 返回原始消息中指定key的值,省略时返回对象第一层对应key的value |
productName | "product001" | 返回带双引号的字符串 |
params.color | "red" | 使用“.”进行字段引用 |
Other.Misc | null | 匹配路径返回null |
Other.Nothing | undefined | 无此路径不返回值(undefined) |
查询JSON数组
数组中的每个值都与索引相关联,通过在数组的字段名称之后使用方括号来完成的。
- 如果方括号包含数字或计算结果为数字的表达式,则数字表示要选择的值的索引。
- 索引从0开始,如果传入的索引不是整数,则向下取整。
- 从数组末尾开始计数的负索引arr[-1]将选择最后一个值,倒数arr[-2]第二个。如果指定的索引超过数组的大小,则不会选择任何内容。
- 如果没有为数组指定索引(即在字段引用之后没有方括号),则整个数组都将被选择。如果数组包含对象,并且位置路径选择了这些对象中的字段,则将查询数组中的每个对象以供选择。
查询语句 | 结果消息 | 描述说明 |
---|---|---|
params.historydDatas[0] | {"key":"temperature","value":50,"time":1465376157007} | 返回指定索引项的值 |
params.historydDatas[-1] | {"key":"speed","value":80,"time":1465376157337} | 返回最后一项 |
params.historydDatas[-2] | {"key":"pressure","value":8.5,"time":1465376157337} | 末尾的负索引计数 |
params.historydDatas[8] | 索引不存在,不返回任何内容 | |
params.historydDatas[0].key | "temperature" | 选择索引对应元素指定项中的字段 |
params.historydDatas | [{"key":"temperature","value":50,"time":1465376157007},{"key":"humidity","value":80,"time":1465376157337},{"key":"pressure","value":8.5,"time":1465376157337},{"key":"speed","value":80,"time":1465376157337}] | 没有索引,返回整个数组) |
params.historydDatas.key | ["temperature","humidity","pressure","speed"] | 返回数组中所有元素对应key的值列表 |
查询顶级数组、嵌套数组和数组展平
规则引擎支持数组格式JSON数据查询,输入数据是一个数组而不是一个对象。
示例JSON文档:
[
{
"ref":[1,2]
},
{
"ref":[3,4]
}
]
如果要选择此顶级数组中的第一个对象,则没有要附加[0]到的字段名称。不能单独使用[0],此时必须使用上下文引用 $ 符号来引用文档的开头。
查询语句 | 结果消息 | 描述说明 |
---|---|---|
$[0] | { "ref": [ 1,2 ] } | $ 表达式的开头指的是整个输入文档 |
$[0].ref | [ 1,2 ] | .ref 这里返回整个内部数组 |
$[0].ref[0] | 1 | 返回内部数组的第一个位置上的元素 |
常用函数
规则引擎支持多种内置函数,支持对原始数据查询结果进行多种变换和简单计算。
常用函数,及其用途和示例如下:
平台预置函数
函数 | 功能描述 | 参数和限制 | 示例 |
---|---|---|---|
$topic() |
获取当前消息的完整topic |
在编辑调试中,由于没有真实的设备,默认返回“system/returned/default/test/topic”,规则运行过程中获取的是发布消息的真实topic 可以与$split()函数结合获取指定topic指定层的字符串 |
$topic() => "$iot/testdevice01/events" $split($topic(), "/")[0]=>"system" |
$clientId() | 获取当前消息发布者的clientid | 在编辑调试中,由于没有真实的设备,默认返回固定的“system_returned_default_test_clientid”,规则运行过程中获取的是发布消息的真实clientid |
$clientId() => "testdevice01" |
日期和时间函数
函数 | 功能描述 | 参数和限制 | 示例 |
---|---|---|---|
$millis() |
获取自1970年1月1日UTC毫秒时间戳 |
-- |
$millis() => 1502700297574 |
$toMillis(timestamp) | 格式化时间转毫秒时间戳 | timestamp,必选,格式化时间字符串。格式示例"2017-11-07T15:07:54.972Z" | $toMillis("2017-11-07T15:07:54.972Z") => 1510067274972 |
数值处理函数
函数 | 功能描述 | 参数和限制 | 示例 |
---|---|---|---|
$number(arg) |
将有数值含义的字符串转换为数值并返回 |
arg,必选,待转换的字符串 |
$number("5") => 5$number(true)=>1a.$number() 等价于$number(a) |
$abs(number) | 获取数值的绝对值 | number,必选,数值类型 | $abs(5) => 5 $abs(-5) => 5a.$abs() 等价于$abs(a) |
$floor(number) | 获取数值向下取整数 | number,必选,数值类型 | $floor(5.3) => 5$floor(5.8) => 5$floor(-5.3) => -6a.$floor() 等价于$floor(a) |
$ceil(number) | 获取数值向上取整数 | number,必选,数值类型 | $ceil(5) => 5$ceil(5.3) => 6$ceil(5.8) => 6$ceil(-5.3) => -5a.$floor() 等价于$floor(a) |
$round(number [, precision]) | 获取数值四舍五入到结果 | number,必选,数值类型 precision,可选,整数数值,四舍五入的位,正整数代表小数位,负整数代表整数位 | $round(123.456) => 123$round(123.456, 2) => 123.46$round(123.456, -1) => 120$round(123.456, -2) => 100$round(11.5) => 12$round(12.5) => 12$round(125, -1) => 120 |
$power(base, exponent) | 获取数值的指定次幂的值 | base,必选,数值类型 exponent,必选,数值类型 | $power(2, 8) => 256$power(2, 0.5) => 1.414213562373$power(2, -2) => 0.25a.$power(-2) 等价于 $power(a,-2) |
$sqrt(number) | 获取数值的开平方根 | number,必选,非负数数值类型 | $sqrt(4) => 2$sqrt(2) => 1.414213562373 |
$random() | 获取0到1之间的随机数浮点数 | $random() => 0.7973541067127 | |
$formatNumber(number, picture) | 将数字转换为指定格式的十进制表示形式 | number,必选,数值类型 picture,必选,字符串,输出的格式模板 | $formatNumber(12345.6, '#,###.00') => "12,345.60"$formatNumber(1234.5678, "00.000e0") => "12.346e2"$formatNumber(0.14, "01%") => "14%" |
$formatBase(number [, radix]) | 将10进制数转换为指定进制数字符串 | number,必选,数值类型 radix,选填,整数,不选时默认为10进制,取值范围为2到36 | $formatBase(100, 2) => "1100100"$formatBase(2555, 16) => "9fb" |
字符串函数
函数 | 功能描述 | 参数和限制 | 示例 |
---|---|---|---|
$string(arg) |
将输入值强制转换为字符串 |
arg,必选,待转换值可以是任意JSON任何数据类型,转换为对应的JSONstr |
$string(5) => "5" |
$length(str) | 获取字符串长度 | str,必选 | $length("Hello World") => 11 |
$substring(str, star[,lenght]) | 截取字符串 | str,必选,待处理值 star,必选,开始索引 length,可选,截取的长度,不传时默认截取到最后 | $substring("Hello World", 3) => "lo World" $substring("Hello World", 3,5)=>"lo Wo" |
$trim(str) | 消除字符串中空字符 | str,必选,待处理值 | $trim(" Hello World ") => "HelloWorld" |
$split(str, separator) | 字符串分割 | str,必选,待处理值 separator,必选,分割符 | $split("so many words", " ") => [ "so", "many", "words" ] |
$join(array) | 将数组拼接为字符串 | array,必选,待处理数组 | $join(['a','b','c']) => "abc" |
$replace(str, pattern, replacement) | 字符串替换 | str,必选,待处理值 pattern,必选,被替换的字符串replacement,必选,替换为的目标字符串 | $replace("John Smith and John Jones", "John", "Mr")=>"Mr Smith and Mr Jones" |
$base64encode(str) | 将字符串转换为base64 | str,必选,待处理值 | $base64encode("myuser:mypass") => "bXl1c2VyOm15cGFzcw==" |
$base64decode(str) | 将base64转换为字符串 | str,必选,待处理值,base64字符串 | $base64decode("bXl1c2VyOm15cGFzcw==") => "myuser:mypass" |
对象函数
函数 | 功能描述 | 参数和限制 | 示例 |
---|---|---|---|
$keys(object) |
返回对象包含所有键的数组 |
object,必选,JSON对象 返回规则: 仅返回输入对象最外层keys的数组 |
$keys($)=>["reqId","method","timestamp","deviceName","productName","params","properties","other"] |
$lookup(object,key) | 返回对象指定key的值 | object,必选,待查询JSON对象key,必选,字符串,待查询的key | $lookup(params,"host")=>"192.166.1.1" |
$each(object, function) | 遍历对象并返回元素被回调函数处理后的数组或对象 | object,必选,待查询JSON对象 function,必选,回调函数 特别注意:当输入对象中包含多个key时函数返回结果为function返回的数据类型组成的数组,当输入对象只包含一个key时,返回结果为function返回的数据类型,所以如果想在返回结果中始终得到数组格式,可以在使用此函数时外层增加[],即 [$each(object, function)] | $each(properties, function($v, $k,$arr) {{"key":$k,"value":$v,"array":$arr}})=>[{"key":"temperature","value":35,"array":{"temperature":35,"humidity":22}},{"key":"humidity","value":22,"array":{"temperature":35,"humidity":22}}] 对象中只包含一个元素({"properties":{"temperature":35}})时: 直接使用:$each(properties, function($v, $k,$arr) {{"key":$k,"value":$v,"array":$arr}})=>{"key":"temperature","value":35,"array":{"temperature":35}}外层包裹[]用法:[$each(properties, function($v, $k,$arr) {{"key":$k,"value":$v,"array":$arr}})]=>[{"key":"temperature","value":35,"array":{"temperature":35}}] |
$merge(array) | 将对象数组转换为对象,返回一个包含对象数组中所有不同key的对象 | array,必选,待处理数组 | $merge(params.historydDatas)=>{"key":"speed","value":80,"time":1465376157337,"other":"something other"} |
$sift(object) | 将对象中属性按回调函数设置的条件进行过滤,返回一个仅保留符合条件属性的新对象 | object,必选,待处理数组 | $sift(properties, function($v, $k,$a) {$k!="temperature" and $k!="var_name1"})=>{"humidity":22} |
$type(value) | 返回对象的数据类型 | value,必选,待处理值数据类型包括"null""number""string""boolean""array""object""function" | $type("abc")=>"string" |
数组函数
函数 | 功能描述 | 参数和限制 | 示例 |
---|---|---|---|
$spread(object) |
将输入对象转为对象数组 |
object,必选,待处理对象 |
$spread(properties)=>[{"temperature":35},{"humidity":22}] |
$append(array1,array2) | 将两个数组拼接为一个数组 | 输入为两个数组 | $append(params.historydDatas,[0,1,2])=>[{"key":"temperature","value":50,"time":1465376157007},{"key":"humidity","value":80,"time":1465376157337},{"key":"pressure","value":8.5,"time":1465376157337},{"key":"speed","value":80,"time":1465376157337},0,1,2] |
高阶函数
函数 | 功能描述 | 参数和限制 | 示例 | |
---|---|---|---|---|
$map(array, function) |
遍历数组并返回一个自定义格式的数组 |
array,必选,待查询JSON数组 function,必选,回调函数,回调中可以获得三个返回参数依次标识数据元素的值、元素索引、原数组 |
$map(params.historydDatas, function($v, $i, $a) { 'Item ' & ($i+1) & ' of ' & $count($a) & ': ' & $v.key })=>["Item 1 of 4: temperature","Item 2 of 4: humidity","Item 3 of 4: pressure","Item 4 of 4: speed"] | |
$filter(array, function) | 过滤数组中指定条件的元素 | array,必选,待查询JSON数组 function,必选,回调函数,回调中可以获得三个返回参数依次标识数据元素的值、元素索引、原数组 | $filter(params.historydDatas, function($v, $i, $a) { $v.key ="temperature" })=>{"key":"temperature","value":50,"time":1465376157007,"other":"something other"} |
二进制(Protobuf)格式数据处理
规则引擎支持二进制 PB 格式的数据进行处理,需要上传样例数据二进制文件,并同时依赖 PB 文件。
具体示例可参考 数据解析模版(含日志数据解析)中内容。