0
# Sequence Nodes
1
2
Sequence nodes provide message flow control and manipulation capabilities for handling arrays, message streams, and batch processing. These nodes enable complex data aggregation, splitting, and ordering operations within Node-RED flows.
3
4
## Capabilities
5
6
### Split Node
7
8
Split messages into sequences based on arrays, objects, or string delimiters. Creates a sequence of individual messages from composite data.
9
10
```javascript { .api }
11
/**
12
* Split node for breaking messages into sequences
13
* Registers as node type: "split"
14
*/
15
function SplitNode(config) {
16
RED.nodes.createNode(this, config);
17
18
// Configuration properties:
19
// config.splt - Split character/delimiter (for strings)
20
// config.spltType - Split type: "str", "len", "stream"
21
// config.arraySplt - Array split mode
22
// config.arraySpltType - Array split type
23
// config.stream - Stream mode for large objects
24
// config.addname - Add property name for object splits
25
}
26
```
27
28
**Usage Examples:**
29
30
```javascript
31
// Split array into individual messages
32
// Input: { payload: [1, 2, 3, 4, 5] }
33
// Output: { payload: 1, parts: {index: 0, count: 5, id: "abc"} }
34
// { payload: 2, parts: {index: 1, count: 5, id: "abc"} }
35
// ... etc
36
37
// Split string by delimiter
38
{
39
"splt": ",",
40
"spltType": "str"
41
}
42
// Input: { payload: "red,green,blue" }
43
// Output: { payload: "red", parts: {index: 0, count: 3, id: "def"} }
44
// { payload: "green", parts: {index: 1, count: 3, id: "def"} }
45
// { payload: "blue", parts: {index: 2, count: 3, id: "def"} }
46
47
// Split object into key-value pairs
48
{
49
"arraySplt": true,
50
"addname": true
51
}
52
// Input: { payload: {name: "John", age: 30, city: "NYC"} }
53
// Output: { payload: "John", topic: "name", parts: {...} }
54
// { payload: 30, topic: "age", parts: {...} }
55
// { payload: "NYC", topic: "city", parts: {...} }
56
```
57
58
### Join Node
59
60
Combine message sequences back into arrays, objects, or concatenated strings. Supports automatic and manual join modes.
61
62
```javascript { .api }
63
/**
64
* Join node for combining message sequences
65
* Registers as node type: "join"
66
*/
67
function JoinNode(config) {
68
RED.nodes.createNode(this, config);
69
70
// Configuration properties:
71
// config.mode - Join mode: "auto", "custom", "reduce"
72
// config.build - Build type: "array", "object", "string", "merged"
73
// config.property - Property to join (default: "payload")
74
// config.propertyType - Property type: "msg", "full"
75
// config.key - Key property for object building
76
// config.joiner - String joiner character
77
// config.joinerType - Joiner type
78
// config.accumulate - Accumulate results
79
// config.timeout - Join timeout in seconds
80
// config.count - Expected message count (manual mode)
81
}
82
```
83
84
**Usage Examples:**
85
86
```javascript
87
// Auto-join split array back together
88
{
89
"mode": "auto",
90
"build": "array"
91
}
92
// Input: Sequence of messages with parts.index/count/id
93
// Output: { payload: [1, 2, 3, 4, 5] }
94
95
// Join messages into object using topic as key
96
{
97
"mode": "custom",
98
"build": "object",
99
"key": "topic",
100
"count": "3"
101
}
102
// Input: { payload: "John", topic: "name" }
103
// { payload: 30, topic: "age" }
104
// { payload: "NYC", topic: "city" }
105
// Output: { payload: {name: "John", age: 30, city: "NYC"} }
106
107
// Join messages into string
108
{
109
"mode": "custom",
110
"build": "string",
111
"joiner": ", ",
112
"count": "3"
113
}
114
// Input: { payload: "red" }, { payload: "green" }, { payload: "blue" }
115
// Output: { payload: "red, green, blue" }
116
117
// Reduce mode for calculations
118
{
119
"mode": "reduce",
120
"build": "merged",
121
"reduceRight": false,
122
"reduceExp": "$A + payload",
123
"reduceInit": "0",
124
"reduceInitType": "num"
125
}
126
```
127
128
### Sort Node
129
130
Sort message sequences by specified properties with configurable sort order.
131
132
```javascript { .api }
133
/**
134
* Sort node for ordering message sequences
135
* Registers as node type: "sort"
136
*/
137
function SortNode(config) {
138
RED.nodes.createNode(this, config);
139
140
// Configuration properties:
141
// config.target - Property to sort by (default: "payload")
142
// config.targetType - Target type: "msg", "seq"
143
// config.msgKey - Message key for sorting
144
// config.msgKeyType - Key type: "elem", "jsonata"
145
// config.seqKey - Sequence key for sorting
146
// config.seqKeyType - Sequence key type
147
// config.order - Sort order: "ascending", "descending"
148
}
149
```
150
151
**Usage Examples:**
152
153
```javascript
154
// Sort by payload value (ascending)
155
{
156
"target": "payload",
157
"order": "ascending"
158
}
159
// Input: { payload: 3, parts: {...} }
160
// { payload: 1, parts: {...} }
161
// { payload: 2, parts: {...} }
162
// Output: { payload: 1, parts: {...} }
163
// { payload: 2, parts: {...} }
164
// { payload: 3, parts: {...} }
165
166
// Sort objects by property (descending)
167
{
168
"target": "payload",
169
"msgKey": "age",
170
"msgKeyType": "elem",
171
"order": "descending"
172
}
173
// Input: { payload: {name: "John", age: 30} }
174
// { payload: {name: "Jane", age: 25} }
175
// { payload: {name: "Bob", age: 35} }
176
// Output: { payload: {name: "Bob", age: 35} }
177
// { payload: {name: "John", age: 30} }
178
// { payload: {name: "Jane", age: 25} }
179
180
// Sort using JSONata expression
181
{
182
"msgKey": "payload.timestamp",
183
"msgKeyType": "jsonata",
184
"order": "ascending"
185
}
186
```
187
188
### Batch Node
189
190
Group messages into batches based on count, time intervals, or other criteria.
191
192
```javascript { .api }
193
/**
194
* Batch node for grouping messages
195
* Registers as node type: "batch"
196
*/
197
function BatchNode(config) {
198
RED.nodes.createNode(this, config);
199
200
// Configuration properties:
201
// config.mode - Batch mode: "count", "interval"
202
// config.count - Messages per batch (count mode)
203
// config.overlap - Overlap count for sliding window
204
// config.interval - Time interval in seconds (interval mode)
205
// config.allowEmptySequence - Allow empty batches
206
// config.topics - Topic grouping
207
}
208
```
209
210
**Usage Examples:**
211
212
```javascript
213
// Batch by message count
214
{
215
"mode": "count",
216
"count": "3",
217
"overlap": "0"
218
}
219
// Input: 6 individual messages
220
// Output: 2 batches of 3 messages each
221
222
// Sliding window batch
223
{
224
"mode": "count",
225
"count": "3",
226
"overlap": "1"
227
}
228
// Creates overlapping batches: [1,2,3], [2,3,4], [3,4,5], etc.
229
230
// Time-based batching
231
{
232
"mode": "interval",
233
"interval": "5"
234
}
235
// Collects messages for 5 seconds, then outputs batch
236
237
// Topic-based grouping
238
{
239
"mode": "count",
240
"count": "2",
241
"topics": true
242
}
243
// Groups messages by topic, batching within each topic
244
```
245
246
## Message Parts Structure
247
248
Sequence nodes use a standard `parts` property to track message sequences:
249
250
```javascript { .api }
251
// Message parts structure for sequence tracking
252
interface MessageParts {
253
id: string; // Unique sequence identifier
254
index: number; // Position in sequence (0-based)
255
count: number; // Total messages in sequence
256
type?: string; // Sequence type: "array", "object", "string"
257
ch?: string; // Character used for string splits
258
key?: string; // Object key (for object sequences)
259
len?: number; // Length information
260
}
261
262
// Example message with parts
263
interface SequenceMessage {
264
payload: any;
265
parts: MessageParts;
266
topic?: string; // May contain key for object sequences
267
[key: string]: any;
268
}
269
```
270
271
## Processing Patterns
272
273
Sequence nodes implement consistent patterns for handling message flows:
274
275
```javascript { .api }
276
// Standard sequence processing pattern
277
this.on("input", function(msg, send, done) {
278
try {
279
if (msg.hasOwnProperty("parts")) {
280
// Handle sequenced message
281
processSequencedMessage(msg);
282
} else {
283
// Handle standalone message
284
processStandaloneMessage(msg);
285
}
286
287
// Check if sequence is complete
288
if (isSequenceComplete()) {
289
var result = buildResult();
290
send(result);
291
}
292
293
done();
294
} catch (error) {
295
done(error);
296
}
297
});
298
299
// Sequence completion detection
300
function isSequenceComplete() {
301
// Check if all expected messages received
302
return receivedCount >= expectedCount;
303
}
304
```
305
306
## Advanced Features
307
308
### Reduce Operations
309
310
Join node supports reduce operations for calculations across sequences:
311
312
```javascript { .api }
313
// Reduce configuration for calculations
314
{
315
"mode": "reduce",
316
"build": "merged",
317
"reduceRight": false,
318
"reduceExp": "$A + payload.value", // JSONata expression
319
"reduceInit": "0", // Initial accumulator value
320
"reduceInitType": "num"
321
}
322
323
// Example reduce operations:
324
// Sum: "$A + payload"
325
// Product: "$A * payload"
326
// Max: "payload > $A ? payload : $A"
327
// Concatenate: "$A & payload"
328
// Count: "$A + 1"
329
```
330
331
### Timeout Handling
332
333
Join node supports timeouts for incomplete sequences:
334
335
```javascript { .api }
336
// Timeout configuration
337
{
338
"timeout": "30", // 30 second timeout
339
"build": "array",
340
"mode": "custom"
341
}
342
343
// Behavior on timeout:
344
// - Sends partial results if any messages received
345
// - Clears internal sequence state
346
// - Continues processing new sequences
347
```
348
349
### Topic-based Grouping
350
351
Batch node can group messages by topic for parallel processing:
352
353
```javascript { .api }
354
// Topic grouping configuration
355
{
356
"mode": "count",
357
"count": "5",
358
"topics": true
359
}
360
361
// Creates separate batches per topic:
362
// Topic "sensor1": [msg1, msg2, msg3, msg4, msg5]
363
// Topic "sensor2": [msg1, msg2, msg3, msg4, msg5]
364
// Each topic maintains independent batch state
365
```
366
367
## Error Handling
368
369
Sequence nodes handle various error conditions:
370
371
```javascript { .api }
372
// Common error scenarios:
373
374
// Missing parts property (join/sort nodes)
375
// Recovery: Treat as single-message sequence
376
377
// Sequence timeout (join node)
378
// Recovery: Send partial results, clear state
379
380
// Invalid sort key (sort node)
381
// Recovery: Skip sorting, pass messages through
382
383
// Memory limits (large sequences)
384
// Recovery: Implement backpressure, limit sequence size
385
```