Switch New in 1.0.0
A router. It tests one field of the message against a table of rules, and the message leaves through the output belonging to the rule that matched. It is the only node with more than one output.
Type: switch · Category: Common · Ports: one input · one output per rule


When to use it
- Sorting one feed into several treatments — critical alarms to a pager, the rest to a log
- Handling the shapes of an inbound REST payload separately without three parallel pipelines
- Guarding an expensive branch so it only runs for the messages that need it
To DROP messages rather than sort them, use RBE — it is one rule, one output and no branch to draw. To take a decision that needs arithmetic or several fields at once, use a Python Script and route on what it returns.
Settings
| Setting | Key | Default | Purpose |
|---|---|---|---|
| Property | property | payload | The field under test. payload, a dotted path into it (payload.sensor.value), topic, or metadata.<key>. |
| Check all rules | checkall | true | On, every matching rule fires and the message goes down each. Off, the first match wins and the rest are not evaluated. |
| Rules | rules | one == rule | The rule table. Each row is one output, top to bottom. |
Each rule has an operator, an operand, and the type to read that operand as.
Operators
| Group | Operators |
|---|---|
| Compare | == · != · < · <= · > · >= · is between (two operands, inclusive) |
| Text | contains · matches regex — both with an optional case-insensitive toggle |
| Presence | is true · is false · is null · is not null · is empty · is not empty |
| Shape | is of type (string, number, boolean, object, array, null) · has key |
| Fallback | otherwise |
Operand types
| Type | Read as |
|---|---|
| text | The literal string. Ordering is alphabetical, so "9" sorts above "10". |
| number | A number. A value under test that is not numeric never matches. |
| boolean | true or false. |
| JSON | Parsed as JSON first, so a rule can compare against an object or an array. |
| message field | Another field of the same message — payload.limit — so a reading can be compared against a setpoint that travelled with it. |
Example — sorting readings into three treatments
Property: payload.temperature
Check all rules: off
Rule 1: >= 80 (number) → output 1
Rule 2: is between 60 and 80 (number) → output 2
Rule 3: otherwise → output 3
In
{ "topic": "Line1/Oven", "payload": { "temperature": 85 } }
{ "topic": "Line1/Oven", "payload": { "temperature": 70 } }
{ "topic": "Line1/Oven", "payload": { "temperature": 41 } }
Out — one message leaves by one output each time:
| Reading | Leaves by | Because |
|---|---|---|
| 85 | output 1 | 85 >= 80 |
| 70 | output 2 | not ≥ 80, and inside 60–80 |
| 41 | output 3 | nothing matched, so otherwise takes it |
The payload is passed through untouched — a Switch decides where a message goes, never what it says.
Wire each output to what should happen:
┌─ 1 → Alarm (raise, critical) → On-Call Roster → Send Email
Industrial I/O → Switch ┼─ 2 → QuestDB (ingress)
└─ 3 → Debug
Check all, or first match?
Off — first match wins is what you want when the rules describe bands of one quantity, as above.
The bands overlap at their edges — 80 satisfies both >= 80 and is between 60 and 80 — and
stopping at the first match is what makes the table read top-down as "critical, else warning, else
normal".
On is what you want when the rules describe independent facts that can all be true at once: "it mentions a work order", "it came from Line 1", "it is over the limit". The message goes down every output whose rule matched.
Gotchas
- A rule you delete takes its output with it, and the outputs below it renumber. Any connection drawn from a removed output is dropped. Settle the order of the rules before wiring the branches.
- otherwise fires only when no ordinary rule matched, wherever it sits in the table. It is not "the last output" — a message that matched rule 1 never reaches it.
- A branch whose output did not fire is skipped, and the skip cascades. The nodes downstream of it do not run, and none of that is an error. It does mean a Join placed after two branches of a Switch will only ever see the branch that fired.
- An invalid regular expression fails the whole node, loudly, rather than becoming a rule that silently never matches. A branch that is never taken is indistinguishable from data that never matched, and that is close to undiagnosable on a live line.
- If nothing matches and there is no otherwise rule, the node reports no rule matched and every branch is skipped. Keep an otherwise output wired to a Debug node while you are building.
- is between does not care which way round the bounds are written: 5..1 means the same range as 1..5, because the order of two bounds is a data-entry detail rather than a way to say "never".