Skip to content

Commit

Permalink
docs(cookbook): add over clause examples (#3280)
Browse files Browse the repository at this point in the history
Signed-off-by: Jiyong Huang <huangjy@emqx.io>
  • Loading branch information
ngjaying authored Oct 12, 2024
1 parent f47289a commit 3853079
Show file tree
Hide file tree
Showing 2 changed files with 240 additions and 25 deletions.
139 changes: 125 additions & 14 deletions docs/en_US/example/change_data_capture.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,33 +2,141 @@

In IoT scenarios, it is a very common scenario to trigger events when indicators change. This article will use current changes as an example to introduce eKuiper SQL rules.

## background
## Background

In this scenario, stream will continuously send the current current data in the form of a stream, as well as the timestamp to which the data belongs. eKuiper rules will accept this data flow and meet the requirements with the defined rules, the data is as follows:
In this scenario, stream will continuously send the current current data in the form of a stream, as well as the
timestamp to which the data belongs. In this document, we will use the sample input data as follows:

```json
{
"current": 300,
"ts": 1,
"deviceId": 1
}
{
"current": 400,
"ts": 2,
"deviceId": 2
}
{
"current": 200,
"ts": 3,
"deviceId": 1
}
{
"current": 200,
"ts": 4,
"deviceId": 2
}
{
"current": 500,
"ts": 5,
"deviceId": 1
}
{
"current": 200,
"ts": 6,
"deviceId": 2
}
{
"current": 400,
"ts": 7,
"deviceId": 1
}
{
"current": 600,
"ts": 8,
"deviceId": 2
}
```

### Trigger When Changed Value Pass Threshold

In IoT applications, users often need to monitor whether sensor values exceed a certain threshold, thereby triggering
alarms or other actions. Simply comparing the current value with the threshold may lead to continuous triggering of
alarms. Therefore, what users might actually need is to trigger an alarm when the value changes from not exceeding the
threshold to exceeding it, which implies a process of judging the change. Let's check how eKuiper can help to fulfill
this requirement.

#### 1. Changed current value exceeds 300

```sql
select current, ts
from demo
where current > 300 and lag(current) <= 300;
```

This rule will record the last data of the current, and then compare it with the current data. Once the conditions are
met, the event will be triggered.

```json
{"current":200,"ts":1}
{"current":400,"ts":2}
{"current":300,"ts":3}
{"current":200,"ts":4}
{
"current": 500,
"ts": 5
}
{
"current": 400,
"ts": 7
}
```

### The current changes from less than 300A to more than 300A
Notice that, this rule will check all deviceIds all together. If you need to separate devices, checkout the next
scenario.

#### 2. Changed current value of a deviceId exceeds 300

```sql
select current, ts from demo where current > 300 and lag(current) < 300;
select current, deviceId, ts
from demo
where current > 300 and lag(current) over (partition by deviceId) < 300;
```

This rule will record the last data of the current, and then compare it with the current data. Once the conditions are met, the event will be triggered.
This rule will record lag value partition by device. Thus the output will be:

```json
{"current":200,"ts":1}
{"current":400,"ts":2} output event
{"current":300,"ts":3}
{"current":200,"ts":4}
{
"current": 500,
"ts": 5,
"deviceId": 1
}
{
"current": 600,
"ts": 8,
"deviceId": 2
}
```

### The total current exceeds 200A for 10 seconds
Although the input stream mixes data from multiple devices, we can still calculate the lag value separately.

#### 3. Changed value of a specific device

If users only care about a specific device, we can use OVER when clause to only calculate state of concerned device.

```sql
select current, deviceId, ts
from demo
where current > 300 and deviceId = 1 and lag(current) over (when deviceId = 1) < 300;
```

The output will be:

```json
{
"current": 500,
"ts": 5,
"deviceId": 1
}
```

In this rule, the where clause has condition `deviceId = 1` to specify the deviceId. And in the lag function, over when
clause limits the lag value to only record when `deviceId=1`. This will only capture changes of device 1, regardless of
other devices in the same stream.

Besides `lag` function, other analytic functions like had_changed also supports the OVER clause to limit the state
dimension. Check [analytic functions](../sqls/functions/analytic_functions.md) for detail.

### Trigger When Passing Threshold for Some Time

```sql
select current from demo group by SLIDINGWINDOW(ss,0,10) over (when current > 200) having min(current) > 200;
Expand All @@ -47,5 +155,8 @@ This rule will open a window when receiving current data above 200A. If the smal
{"current":300,"ts":8}
{"current":300,"ts":9}
{"current":300,"ts":10}
{"current":300,"ts":11} output event
{
"current": 300,
"ts": 11
} Output Event
```
126 changes: 115 additions & 11 deletions docs/zh_CN/example/change_data_capture.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,30 +4,134 @@

## 背景

在该场景中,stream 会以流的形式不断发送当前电流的数据,以及该数据所属的时间戳。eKuiper 规则将接受该数据流,并以定义的规则来满足需求, 数据如下所示:
在该场景中,stream 会以流的形式不断发送当前电流的数据,以及该数据所属的时间戳。本文中,我们将使用如下模拟输入数据:

```json
{"concurrency":200,"ts":1}
{"concurrency":400,"ts":2}
{"concurrency":300,"ts":3}
{"concurrency":200,"ts":4}
{
"current": 300,
"ts": 1,
"deviceId": 1
}
{
"current": 400,
"ts": 2,
"deviceId": 2
}
{
"current": 200,
"ts": 3,
"deviceId": 1
}
{
"current": 200,
"ts": 4,
"deviceId": 2
}
{
"current": 500,
"ts": 5,
"deviceId": 1
}
{
"current": 200,
"ts": 6,
"deviceId": 2
}
{
"current": 400,
"ts": 7,
"deviceId": 1
}
{
"current": 600,
"ts": 8,
"deviceId": 2
}
```

### 电流由小于300A变为大于300A
### 当值变化为超过阈值时触发

在物联网应用中,用户经常需要监控传感器数值是否超过某个阈值,从而触发报警等动作。通过简单的比较当前值与阈值大小,可能会导致报警的持续触发。因此,用户可能更需要的是当数值由不超过阈值变为超过阈值时触发报警,其中隐含了判断变化的过程。以下为几个常见的场景:

#### 1. 电流变化后超过阈值

```sql
select concurrency, ts from demo where concurrency > 300 and lag(concurrency) < 300;
select concurrency, ts
from demo
where concurrency > 300
and lag(concurrency) <= 300;
```

该规则会记录电流上一次的数据,然后和当前数据进行比对,一旦满足条件,则进行事件触发。

```json
{"concurrency":200,"ts":1}
{"concurrency":400,"ts":2} 事件触发
{"concurrency":300,"ts":3}
{"concurrency":200,"ts":4}
{
"current": 400,
"ts": 2
}
{
"current": 500,
"ts": 5
}
{
"current": 400,
"ts": 7
}
```

请注意,该规则会检测整个数据流(包含所有设备的值)的变化。如果需要区分设备,请看下面的场景。

#### 2. 各设备的电流变化后超过阈值

```sql
select current, deviceId, ts
from demo
where current > 300 and lag(current) over (partition by deviceId) < 300;
```

该规则会记录每个设备的上一次的数据与该设备当前数据进行比较。输出结果如下:

```json
{
"current": 500,
"ts": 5,
"deviceId": 1
}
{
"current": 600,
"ts": 8,
"deviceId": 2
}
```

可见,在输入数据包含了多个设备的电流值的情况下,我们仍然可以基于设备进行触发。

#### 3. 某个设备的电流变化后超过阈值

假设用户只关心某个具体的设备如 deviceId 为 1 的设备,我们可以通过 OVER WHEN 语句来限定 lag 的范围。

```sql
select current, deviceId, ts
from demo
where current > 300 and deviceId = 1 and lag(current) over (when deviceId = 1) < 300;
```

输出结果如下:

```json
{
"current": 500,
"ts": 5,
"deviceId": 1
}
```

在此规则中,WHERE 语句里添加了条件 `deviceId = 1`,这样只会针对该设备进行计算。另外在 lag 函数中,OVER WHEN 条件同样限定了
deviceId,这样与当前设备值比较的只会是该设备上一次的值,排除了数据流中其余设备数据的影响。

除了 `lag` 函数,其余分析函数,例如 had_changed 等都支持 OVER
子句来限定状态的维度。详细信息请查看[分析函数](../sqls/functions/analytic_functions.md)

### 总电流持续10s超过200A

```sql
Expand Down

0 comments on commit 3853079

Please sign in to comment.