Skip to main content
Version: Next

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

The Switch node as it appears on the pipeline canvas.The Switch node as it appears on the pipeline canvas.

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
Reach for something else when

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

SettingKeyDefaultPurpose
PropertypropertypayloadThe field under test. payload, a dotted path into it (payload.sensor.value), topic, or metadata.<key>.
Check all rulescheckalltrueOn, every matching rule fires and the message goes down each. Off, the first match wins and the rest are not evaluated.
Rulesrulesone == ruleThe 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

GroupOperators
Compare== · != · < · <= · > · >= · is between (two operands, inclusive)
Textcontains · matches regex — both with an optional case-insensitive toggle
Presenceis true · is false · is null · is not null · is empty · is not empty
Shapeis of type (string, number, boolean, object, array, null) · has key
Fallbackotherwise

Operand types

TypeRead as
textThe literal string. Ordering is alphabetical, so "9" sorts above "10".
numberA number. A value under test that is not numeric never matches.
booleantrue or false.
JSONParsed as JSON first, so a rule can compare against an object or an array.
message fieldAnother 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:

ReadingLeaves byBecause
85output 185 >= 80
70output 2not ≥ 80, and inside 60–80
41output 3nothing 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".

See also