Skip to content

Commit 61f498c

Browse files
authored
Merge pull request #313559 from sethmanheim/regrp4
4: more dataflow articles
2 parents 7e09897 + 9dd632c commit 61f498c

9 files changed

Lines changed: 820 additions & 0 deletions

File tree

articles/iot-operations/connect-to-cloud/howto-create-dataflow-graph.md

Lines changed: 448 additions & 0 deletions
Large diffs are not rendered by default.
Lines changed: 372 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,372 @@
1+
---
2+
title: Filter data in a data flow
3+
description: Filter messages in a data flow based on conditions using Azure IoT Operations.
4+
author: sethmanheim
5+
ms.author: sethm
6+
ms.service: azure-iot-operations
7+
ms.subservice: azure-data-flows
8+
ms.topic: how-to
9+
ms.date: 03/19/2026
10+
ai-usage: ai-assisted
11+
12+
#CustomerIntent: As an operator, I want to filter data in a data flow based on conditions.
13+
---
14+
15+
# Filter data in a data flow
16+
17+
[!INCLUDE [kubernetes-management-preview-note](../includes/kubernetes-management-preview-note.md)]
18+
19+
Use the filter stage in a data flow to drop messages that match a condition. When a filter expression evaluates to true, the message is **dropped**. When the expression evaluates to false, the message passes through to the next stage.
20+
21+
You can define multiple filter rules. Each rule specifies input fields and a boolean expression. The rules use OR logic: if **any** rule evaluates to true, the message is dropped.
22+
23+
<!-- > [!TIP]
24+
> For richer filtering capabilities, including branch routing, concat merging, and schema validation, see [Filter and route data with data flow graphs](howto-dataflow-graphs-filter-route.md). -->
25+
26+
## Configure a filter
27+
28+
Each filter rule has the following properties:
29+
30+
| Property | Required | Description |
31+
|----------|----------|-------------|
32+
| `inputs` | Yes | List of field paths to read from the incoming message. Assigned positional variables: the first input is `$1`, the second is `$2`, and so on. |
33+
| `expression` | Yes | Boolean expression evaluated against each message. If true, the message is dropped. |
34+
| `description` | No | Human-readable description of the filter rule. |
35+
36+
### Use last known value
37+
38+
Append `? $last` to an input to use the last known value when the field is missing from the current message. This approach is useful for sparse data where not every message contains every field.
39+
40+
## Examples
41+
42+
### Filter by a threshold
43+
44+
Drop messages where temperature is 20 or below:
45+
46+
# [Operations experience](#tab/portal)
47+
48+
1. Under **Transform (optional)**, select **Filter** > **Add**.
49+
50+
:::image type="content" source="media/howto-create-dataflow/dataflow-filter.png" alt-text="Screenshot using operations experience to add a filter transform." lightbox="media/howto-create-dataflow/dataflow-filter.png":::
51+
52+
1. Enter the following settings:
53+
54+
| Setting | Description |
55+
|--------------------|-------------|
56+
| Filter condition | `temperature <= 20` |
57+
| Description | Drop low temperature readings |
58+
59+
In the filter condition field, enter `@` or select **Ctrl + Space** to choose datapoints from a dropdown.
60+
61+
1. Select **Apply**.
62+
63+
# [Azure CLI](#tab/cli)
64+
65+
```json
66+
{
67+
"operationType": "BuiltInTransformation",
68+
"builtInTransformationSettings": {
69+
"filter": [
70+
{
71+
"inputs": [
72+
"temperature"
73+
],
74+
"expression": "$1 <= 20"
75+
}
76+
]
77+
}
78+
}
79+
```
80+
81+
# [Bicep](#tab/bicep)
82+
83+
```bicep
84+
builtInTransformationSettings: {
85+
filter: [
86+
{
87+
inputs: [
88+
'temperature'
89+
]
90+
expression: '$1 <= 20'
91+
}
92+
]
93+
}
94+
```
95+
96+
# [Kubernetes (preview)](#tab/kubernetes)
97+
98+
```yaml
99+
builtInTransformationSettings:
100+
filter:
101+
- inputs:
102+
- temperature
103+
expression: "$1 <= 20"
104+
```
105+
106+
---
107+
108+
### Filter with last known value
109+
110+
Use the last known temperature value if the current message doesn't include it. Drop messages where the last known temperature is 20 or below:
111+
112+
# [Operations experience](#tab/portal)
113+
114+
In the filter condition field, enter `@temperature ? $last <= 20`.
115+
116+
# [Azure CLI](#tab/cli)
117+
118+
```json
119+
{
120+
"operationType": "BuiltInTransformation",
121+
"builtInTransformationSettings": {
122+
"filter": [
123+
{
124+
"inputs": [
125+
"$source.temperature ? $last"
126+
],
127+
"expression": "$1 <= 20"
128+
}
129+
]
130+
}
131+
}
132+
```
133+
134+
# [Bicep](#tab/bicep)
135+
136+
```bicep
137+
builtInTransformationSettings: {
138+
filter: [
139+
{
140+
inputs: [
141+
'temperature ? $last'
142+
]
143+
expression: '$1 <= 20'
144+
}
145+
]
146+
}
147+
```
148+
149+
# [Kubernetes (preview)](#tab/kubernetes)
150+
151+
```yaml
152+
builtInTransformationSettings:
153+
filter:
154+
- inputs:
155+
- temperature ? $last
156+
expression: "$1 <= 20"
157+
```
158+
159+
---
160+
161+
### Filter with multiple conditions
162+
163+
Drop messages where the product of temperature and humidity is 100,000 or more:
164+
165+
# [Operations experience](#tab/portal)
166+
167+
In the filter condition field, enter `@temperature * @humidity >= 100000`.
168+
169+
# [Azure CLI](#tab/cli)
170+
171+
```json
172+
{
173+
"operationType": "BuiltInTransformation",
174+
"builtInTransformationSettings": {
175+
"filter": [
176+
{
177+
"inputs": [
178+
"temperature.Value",
179+
"humidity.Value"
180+
],
181+
"expression": "$1 * $2 >= 100000"
182+
}
183+
]
184+
}
185+
}
186+
```
187+
188+
# [Bicep](#tab/bicep)
189+
190+
```bicep
191+
builtInTransformationSettings: {
192+
filter: [
193+
{
194+
inputs: [
195+
'temperature.Value'
196+
'humidity.Value'
197+
]
198+
expression: '$1 * $2 >= 100000'
199+
}
200+
]
201+
}
202+
```
203+
204+
# [Kubernetes (preview)](#tab/kubernetes)
205+
206+
```yaml
207+
builtInTransformationSettings:
208+
filter:
209+
- inputs:
210+
- temperature.Value
211+
- humidity.Value
212+
expression: "$1 * $2 >= 100000"
213+
```
214+
215+
---
216+
217+
### Filter with enriched data
218+
219+
If you configured an [enrichment dataset](concept-dataflow-enrich.md), you can use enriched fields in filter conditions. For example, filter against a device-specific limit from a state store dataset:
220+
221+
# [Operations experience](#tab/portal)
222+
223+
Currently, enrichment-based filtering isn't available in the operations experience.
224+
225+
# [Azure CLI](#tab/cli)
226+
227+
```json
228+
{
229+
"operationType": "BuiltInTransformation",
230+
"builtInTransformationSettings": {
231+
"datasets": [
232+
{
233+
"key": "device_limits",
234+
"inputs": [
235+
"$source.deviceId",
236+
"$context(device_limits).deviceId"
237+
],
238+
"expression": "$1 == $2"
239+
}
240+
],
241+
"filter": [
242+
{
243+
"inputs": [
244+
"temperature",
245+
"$context(device_limits).maxTemperature"
246+
],
247+
"expression": "$1 <= $2"
248+
}
249+
]
250+
}
251+
}
252+
```
253+
254+
# [Bicep](#tab/bicep)
255+
256+
```bicep
257+
builtInTransformationSettings: {
258+
datasets: [
259+
{
260+
key: 'device_limits'
261+
inputs: [
262+
'$source.deviceId'
263+
'$context(device_limits).deviceId'
264+
]
265+
expression: '$1 == $2'
266+
}
267+
]
268+
filter: [
269+
{
270+
inputs: [
271+
'temperature'
272+
'$context(device_limits).maxTemperature'
273+
]
274+
expression: '$1 <= $2'
275+
}
276+
]
277+
}
278+
```
279+
280+
# [Kubernetes (preview)](#tab/kubernetes)
281+
282+
```yaml
283+
builtInTransformationSettings:
284+
datasets:
285+
- key: device_limits
286+
inputs:
287+
- $source.deviceId
288+
- $context(device_limits).deviceId
289+
expression: "$1 == $2"
290+
filter:
291+
- inputs:
292+
- temperature
293+
- $context(device_limits).maxTemperature
294+
expression: "$1 <= $2"
295+
```
296+
297+
---
298+
299+
This example drops messages where the temperature exceeds the device-specific maximum from the state store.
300+
301+
### Multiple filter rules
302+
303+
You can define multiple filter rules. All rules use OR logic: if **any** rule evaluates to true, the message is dropped:
304+
305+
# [Operations experience](#tab/portal)
306+
307+
Under **Transform (optional)**, select **Filter** > **Add** multiple times to add additional filter rules.
308+
309+
# [Azure CLI](#tab/cli)
310+
311+
```json
312+
{
313+
"operationType": "BuiltInTransformation",
314+
"builtInTransformationSettings": {
315+
"filter": [
316+
{
317+
"inputs": ["temperature"],
318+
"expression": "$1 <= 20",
319+
"description": "Drop low temperatures"
320+
},
321+
{
322+
"inputs": ["humidity"],
323+
"expression": "$1 >= 80",
324+
"description": "Drop high humidity readings"
325+
}
326+
]
327+
}
328+
}
329+
```
330+
331+
# [Bicep](#tab/bicep)
332+
333+
```bicep
334+
builtInTransformationSettings: {
335+
filter: [
336+
{
337+
inputs: ['temperature']
338+
expression: '$1 <= 20'
339+
description: 'Drop low temperatures'
340+
}
341+
{
342+
inputs: ['humidity']
343+
expression: '$1 >= 80'
344+
description: 'Drop high humidity readings'
345+
}
346+
]
347+
}
348+
```
349+
350+
# [Kubernetes (preview)](#tab/kubernetes)
351+
352+
```yaml
353+
builtInTransformationSettings:
354+
filter:
355+
- inputs:
356+
- temperature
357+
expression: "$1 <= 20"
358+
description: Drop low temperatures
359+
- inputs:
360+
- humidity
361+
expression: "$1 >= 80"
362+
description: Drop high humidity readings
363+
```
364+
365+
---
366+
367+
## Related content
368+
369+
- [Map data by using data flows](concept-dataflow-mapping.md)
370+
- [Enrich data by using data flows](concept-dataflow-enrich.md)
371+
<!-- - [Filter and route data with data flow graphs](howto-dataflow-graphs-filter-route.md) -->
372+
- [Create a data flow](howto-create-dataflow.md)
47.3 KB
Loading
102 KB
Loading
54.3 KB
Loading
86.7 KB
Loading
139 KB
Loading
74.3 KB
Loading
115 KB
Loading

0 commit comments

Comments
 (0)