Will SORT Node sort multiple arrays

I am curious if the SORT Node would be used for this situation.

If my flow contains a payloads like -
//newTagRead = {"payload":{"epc":flow.rfid[i].epc,"time":currentTime, "ip":flow.rfid[i].ip, "strength":flow.rfid[i].nbRSSIdb}}; which may have 1 - 4 arrays, would I be able to set up a SORT to only pass the array with the highest value of the nbRSSIdb which will be an integer?

Sounds like a perfect use for a JSONata expression...

If you can post a sample of the JSON dataset, I'll be glad to take a whack at it.

Same problem and indeed JSONata it's a killer !

For people who have this need Check order by ^(...) https://docs.jsonata.org/path-operators#order-by-

like PAYLOAD^(EAN,>PRICE) for sort on EAN as first ordering key and price (DESC) for suborder

@bug00

I just can't bring myself to learn JSONata - for several reasons but I thought this looked interesting for sorting arrays - so thought its time to get to grips with it.

I prepared an array of 2616 objects & ran it though a normal function, unsafe function and a change set to JSONata (data generated here)
The measurement is done via a home made subflow making use of regular JS Dates (so only ms accuracy) but reasonably representative.

Input data.

array2616.json (3.4 MB)

The flow...

[{"id":"9a693308.7ebaf","type":"subflow","name":"flow-performance","info":"","category":"","in":[{"x":80,"y":100,"wires":[{"id":"7fc82258.93e36c"}]}],"out":[{"x":440,"y":100,"wires":[{"id":"7fc82258.93e36c","port":0}]}],"env":[{"name":"name","type":"str","value":"measure","ui":{"icon":"font-awesome/fa-tag","label":{"en-US":"Name"},"type":"input","opts":{"types":["str","env"]}}},{"name":"operation","type":"str","value":"start","ui":{"icon":"font-awesome/fa-cog","label":{"en-US":"Operation"},"type":"select","opts":{"opts":[{"l":{"en-US":"start"},"v":"start"},{"l":{"en-US":"stop"},"v":"stop"},{"l":{"en-US":"msg.topic"},"v":"msg.topic"},{"l":{"en-US":"msg.operation"},"v":"msg.operation"},{"l":{"en-US":"msg.payload"},"v":"msg.payload"}]}}}],"color":"#DDAA99"},{"id":"7fc82258.93e36c","type":"function","z":"9a693308.7ebaf","name":"do operation","func":"var name = msg.perfName || env.get(\"name\");\nvar operation = msg.perfOperation || env.get(\"operation\");\nvar measures = global.get(\"flow-performance\") || {};\nvar measure = measures[name] || {};\n\nfunction doOp(measure, op){\n    if(operation === \"start\"){\n        measure.start = Date.now();//change to process.hrtime\n        measure.stop = null;\n        measure.durationMs = null;\n    } else if(operation === \"stop\") {\n        measure.stop = Date.now();//change to process.hrtime\n        measure.durationMs = measure.start ? measure.stop - measure.start : null;\n        msg._performance = measure;\n    }\n}\n\n\nif(operation === \"start\"){\n    doOp(measure, operation);\n} else if(operation === \"stop\") {\n    doOp(measure, operation);\n} else if(operation === \"msg.topic\") {\n    operation = msg.topic;\n    doOp(measure, operation);\n} else if(operation === \"msg.operation\") {\n    operation = msg.operation;\n    doOp(measure, operation);\n} else if(operation === \"msg.payload\") {\n    operation = msg.payload;\n    doOp(measure, operation);\n} else {\n    return msg;    \n}\nmeasures[name] = measure;\nglobal.set(\"flow-performance\", measures);\n\nreturn msg;","outputs":1,"noerr":0,"x":250,"y":100,"wires":[[]]},{"id":"e913f458.ab41f8","type":"file in","z":"96dcfc28.b1202","name":"","filename":"c:/temp/array2616.json","format":"utf8","chunk":false,"sendError":false,"encoding":"none","x":320,"y":120,"wires":[["ef36d18c.0dd4c"]]},{"id":"f6cbf90b.0f6458","type":"inject","z":"96dcfc28.b1202","name":"function","topic":"function","payload":"function","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":110,"y":80,"wires":[["e913f458.ab41f8"]]},{"id":"ef36d18c.0dd4c","type":"json","z":"96dcfc28.b1202","name":"","property":"payload","action":"","pretty":false,"x":530,"y":120,"wires":[["f802e9c.a2ed118","8ec2b68f.e41318"]]},{"id":"f802e9c.a2ed118","type":"debug","z":"96dcfc28.b1202","name":"","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":730,"y":120,"wires":[]},{"id":"2b711f14.a0103","type":"inject","z":"96dcfc28.b1202","name":"JSONata","topic":"JSONata","payload":"JSONata","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":120,"y":160,"wires":[["e913f458.ab41f8"]]},{"id":"5be084ef.8c50fc","type":"inject","z":"96dcfc28.b1202","name":"unsafe","topic":"unsafe","payload":"unsafe","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":110,"y":120,"wires":[["e913f458.ab41f8"]]},{"id":"8ec2b68f.e41318","type":"switch","z":"96dcfc28.b1202","name":"","property":"topic","propertyType":"msg","rules":[{"t":"eq","v":"function","vt":"str"},{"t":"eq","v":"JSONata","vt":"str"},{"t":"eq","v":"unsafe","vt":"str"}],"checkall":"true","repair":false,"outputs":3,"x":270,"y":240,"wires":[["734f26b3.087368"],["4ecf1ecd.cb896"],["f46cde18.715be"]]},{"id":"734f26b3.087368","type":"subflow:9a693308.7ebaf","z":"96dcfc28.b1202","name":"normalFunction","env":[{"name":"name","value":"normalFunction","type":"str"}],"x":460,"y":200,"wires":[["e5cab1f9.84ec6"]]},{"id":"bc342cd7.9829","type":"subflow:9a693308.7ebaf","z":"96dcfc28.b1202","name":"normalFunction","env":[{"name":"name","value":"normalFunction","type":"str"},{"name":"operation","value":"stop","type":"str"}],"x":840,"y":200,"wires":[["b810b60b.e237c8"]]},{"id":"4ecf1ecd.cb896","type":"subflow:9a693308.7ebaf","z":"96dcfc28.b1202","name":"JSONata","env":[{"name":"name","value":"JSONata","type":"str"}],"x":440,"y":240,"wires":[["73113ba5.b169e4"]]},{"id":"b69158b5.88e9c8","type":"subflow:9a693308.7ebaf","z":"96dcfc28.b1202","name":"JSONata","env":[{"name":"name","value":"JSONata","type":"str"},{"name":"operation","value":"stop","type":"str"}],"x":820,"y":240,"wires":[["d4c990c1.ddb8f"]]},{"id":"f46cde18.715be","type":"subflow:9a693308.7ebaf","z":"96dcfc28.b1202","name":"unsafeFunction","env":[{"name":"name","value":"unsafeFunction","type":"str"}],"x":460,"y":280,"wires":[["4449e71c.3b62c8"]]},{"id":"7fee5e7a.a804c","type":"subflow:9a693308.7ebaf","z":"96dcfc28.b1202","name":"unsafeFunction","env":[{"name":"name","value":"unsafeFunction","type":"str"},{"name":"operation","value":"stop","type":"str"}],"x":840,"y":280,"wires":[["d8872368.e3e0d"]]},{"id":"e5cab1f9.84ec6","type":"function","z":"96dcfc28.b1202","name":"","func":"msg.payload.sort((a,b) => {\n    if(a.age < b.age){\n        return -1;\n    }else if(a.age > b.age){\n        return 1;\n    }else{\n        return 0;\n    }\n})\n\nreturn msg;","outputs":1,"noerr":0,"x":630,"y":200,"wires":[["bc342cd7.9829"]]},{"id":"4449e71c.3b62c8","type":"unsafe-function","z":"96dcfc28.b1202","name":"","func":"msg.payload.sort((a,b) => {\n    if(a.age < b.age){\n        return -1;\n    }else if(a.age > b.age){\n        return 1;\n    }else{\n        return 0;\n    }\n})\n\nreturn msg;","outputs":1,"noerr":0,"x":630,"y":280,"wires":[["7fee5e7a.a804c"]]},{"id":"73113ba5.b169e4","type":"change","z":"96dcfc28.b1202","name":"","rules":[{"t":"set","p":"payload","pt":"msg","to":"payload^(age)","tot":"jsonata"}],"action":"","property":"","from":"","to":"","reg":false,"x":660,"y":240,"wires":[["b69158b5.88e9c8"]]},{"id":"b810b60b.e237c8","type":"debug","z":"96dcfc28.b1202","name":"","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":1010,"y":200,"wires":[]},{"id":"d4c990c1.ddb8f","type":"debug","z":"96dcfc28.b1202","name":"","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":1010,"y":240,"wires":[]},{"id":"d8872368.e3e0d","type":"debug","z":"96dcfc28.b1202","name":"","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","x":1010,"y":280,"wires":[]}]

The results...

image

In summary,

  • unsafe function won by 1 or 2 ms (average 4ms) most times
  • normal function was 2nd (average about 5ms)
  • JSONata was always last and never quicker than 3883ms

I ran this about 10 times.

Guess I'll stick with what I know (unless I did something wrong?)!

2 Likes

Just ran the test again on my intel-nuc using latest node-red version. So the relative differences are still the same.

image

Of course this test specifically tests the performance of sorting a big json array (2617 elements - 3.6MB of data).

FYI my node-red version:

Starting node-red ...
> node-red-docker@1.1.3 start /usr/src/node-red
> node $NODE_OPTIONS node_modules/node-red/red.js $FLOWS "--userDir" "/data"
18 Sep 15:10:33 - [info] 
Welcome to Node-RED
===================
18 Sep 15:10:33 - [info] Node-RED version: v1.1.3
18 Sep 15:10:33 - [info] Node.js  version: v12.18.3
18 Sep 15:10:33 - [info] Linux 4.18.0-193.6.3.el8_2.x86_64 x64 LE

I have also reported these findings in:

1 Like