JQ 函数

JQJQ 函数 - 图1 (opens new window) 是一款功能强大的命令行工具和编程语言,主要用于转换和查询 JSONJQ 函数 - 图2 (opens new window) 编码的消息。

对于规则 SQL 及其内置函数很难或无法实现的 JSON 消息处理,使用 JQ 函数可以很方便地实现。

如何使用

EMQX 规则 SQL 通过以下函数集成了 JQ:

函数参数返回值
jq JQ 函数 - 图31. 有效的 jq 程序字符串
2. JSON 编码的字符串或对象
3.执行超时(可选,单位为毫秒,默认为 10 秒)
返回值为执行生成生成的 JSON 对象列表。如果执行超时或者 JQ 程序抛出异常,该函数将抛出异常。

默认执行超时可通过 rule_engine.jq_function_default_timeout 配置。

JQ 同时也是一个图灵完备的编程语言,JQ 官方文档JQ 函数 - 图4 (opens new window) 是学习如何编写 JQ 的最佳指南,您也可以在 JQ PlaygroundJQ 函数 - 图5 (opens new window) 或本地安装后进行学习与测试。

以下是一些简单的 jq 函数调用及其结果的示例。

示例 1

简单处理示例:

  1. jq('.', '{"temperature": 10}') =
  2. [json_decode('{"temperature": 10}')]
  3. jq('.', json_decode('{"temperature": 10}')) =
  4. [json_decode('{"temperature": 10}')]
  5. jq('.temperature', '{"temperature": 10}') =
  6. [10]
  7. jq('{temperature_C:.temperature,
  8. temperature_F: (.temperature * 1.8 + 32)}',
  9. '{"temperature": 10}') =
  10. [json_decode('{"temperature_C": 10, "temperature_F": 50}')]
  11. jq('.temperature,(.temperature * 1.8 + 32)', '{"temperature": 10}') =
  12. [10, 50]

示例 2

上面的例子只是浅尝辄止,展示了 JQ 能做什么。

下面提供了一个更复杂的 JQ 程序的示例,展示了如何将 jq 函数与 FOREACH 语句结合起来,将 JQ 的输出分成多个消息:

  1. FOREACH jq('def rem_first:
  2. if length > 2 then del(.[0]) else . end;
  3. def rem_last:
  4. if length > 1 then del(.[-1]) else . end;
  5. .date as $date |
  6. .sensors[] |
  7. (.data | sort | rem_first | rem_last | add / length) as $average |
  8. {$average, $date}',
  9. payload)
  10. FROM "jq_demo/complex_rule/jq/#"

对应的消息 payload 的示例:

  1. {
  2. "date": "2020-04-24",
  3. "sensors": [
  4. {
  5. "name": "a",
  6. "data": [3,1,2,4,5,5]
  7. },
  8. {
  9. "name": "b",
  10. "data": [1,-100,2,3,4,5,2000]
  11. },
  12. {
  13. "name": "c",
  14. "data": [3, 7, 9]
  15. }
  16. ]
  17. }

上面的规则 SQL 片段将为输入数据中的每个传感器创建一条输出消息。每个消息都是一个 JSON 对象,其中包含一个日期字段,以及一个去掉最大值和最小值之后的传感器数据的平均值的字段(假定它们可能是异常值)。

因此,三条输出消息的 payload 分别为:

消息 1:

  1. {
  2. "average": 3.5,
  3. "date": "2020-04-24"
  4. }

消息 2:

  1. {
  2. "average": 3,
  3. "date": "2020-04-24"
  4. }

消息 3:

  1. {
  2. "average": 7,
  3. "date": "2020-04-24"
  4. }

注意事项

一般情况下 JQ 程序仅用来做 JSON 数据的简单转换或者过滤,如果有必要,也可以使用 JQ 执行复杂的计算。 但是,不建议在规则中执行长时间运行的计算,因为这会大大降低 EMQX 处理新消息的速度。

EMQX 提供了 JQ 超时配置,防止由于错误的 JQ 程序(如陷入死循环)占用 EMQX 运行资源,进而影响您的业务。