首页 > 解决方案 > Node-RED:将具有相同 ID 的消息合并/加入到一条消息中

问题描述

示例流程

我们在 Node-RED 中有这个示例流程。传入数据通过 Trigger 和“DoSometh”进行模拟。我们有一个用户名和一个公司名称。对于两者,我们都想从数据库中获取 ID。这里由函数“FetchUser”和“FetchCompany”模拟。两者都返回一个递增的计数器。因为在现实世界中,每秒可能有多个请求/触发器,速度如此之快,以至于数据库可能不够快,无法在下一个请求到达之前获取数据。为了模拟这一点,我有 2 秒的延迟。现在连续 5 次快速单击 Trigger 时,只生成一个用户“5”和公司“1”的调试输出,因此丢失了 4 个请求。由于每个触发器都会生成一个唯一的消息 ID,因此应该可以加入所有相应的消息,并且不会丢失任何消息。

导出的 Node-RED 代码用于导入

[{"id":"f265141.b1fe4e8","type":"tab","label":"Flow 1","disabled":false,"info":""},{"id":"7cae48f.189e438","type":"inject","z":"f265141.b1fe4e8","name":"","topic":"","payload":"Trigger","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":170,"y":340,"wires":[["8a2175a4.921"]]},{"id":"8a2175a4.921","type":"function","z":"f265141.b1fe4e8","name":"DataInputSimulation","func":"user=\"user@example.com\";\ncompany=\"ExampleCorp\";\nmsg.payload = {};\nmsg.payload.user = user;\nmsg.payload.company=company;\nreturn msg;","outputs":1,"noerr":0,"x":420,"y":340,"wires":[["474672db.36bd14","6c146c08.d0e884"]]},{"id":"474672db.36bd14","type":"change","z":"f265141.b1fe4e8","name":"FetchUser","rules":[{"t":"set","p":"payload","pt":"msg","to":"payload.user","tot":"msg"},{"t":"set","p":"topic","pt":"msg","to":"user","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":610,"y":280,"wires":[["d7c10a91.8cf49"]]},{"id":"6c146c08.d0e884","type":"change","z":"f265141.b1fe4e8","name":"FetchCompany","rules":[{"t":"set","p":"payload","pt":"msg","to":"payload.company","tot":"msg"},{"t":"set","p":"topic","pt":"msg","to":"company","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":600,"y":380,"wires":[["6cd41950.b1f0b"]]},{"id":"d7c10a91.8cf49","type":"function","z":"f265141.b1fe4e8","name":"FetchUser","func":"if (typeof context.zaehler === 'undefined')\n{\n    context.zaehler=0;\n}\ncontext.zaehler++;\nmsg.payload = context.zaehler;\nmsg.parts = {};\nmsg.parts.id = msg._msgid;\nmsg.parts.index = 0;\nmsg.parts.count = 2;\nreturn msg;","outputs":1,"noerr":0,"x":830,"y":280,"wires":[["50504a67.e8a5c4","409aeeb4.586b28"]]},{"id":"6cd41950.b1f0b","type":"function","z":"f265141.b1fe4e8","name":"FetchCompany","func":"if (typeof context.zaehler === 'undefined')\n{\n    context.zaehler=0;\n}\ncontext.zaehler++;\nmsg.payload = context.zaehler;\nmsg.parts = {};\nmsg.parts.id = msg._msgid;\nmsg.parts.index = 1;\nmsg.parts.count = 2;\nreturn msg;","outputs":1,"noerr":0,"x":840,"y":380,"wires":[["3f37bb6c.7c7484","955cad64.587d28"]]},{"id":"50504a67.e8a5c4","type":"debug","z":"f265141.b1fe4e8","name":"","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","x":1090,"y":280,"wires":[]},{"id":"3f37bb6c.7c7484","type":"debug","z":"f265141.b1fe4e8","name":"","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","x":1090,"y":380,"wires":[]},{"id":"409aeeb4.586b28","type":"join","z":"f265141.b1fe4e8","name":"","mode":"custom","build":"object","property":"payload","propertyType":"msg","key":"topic","joiner":"\\n","joinerType":"str","accumulate":false,"timeout":"","count":"2","reduceRight":false,"reduceExp":"","reduceInit":"","reduceInitType":"num","reduceFixup":"","x":640,"y":580,"wires":[["c93fce1a.d3aa6"]]},{"id":"c93fce1a.d3aa6","type":"debug","z":"f265141.b1fe4e8","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","x":900,"y":600,"wires":[]},{"id":"955cad64.587d28","type":"delay","z":"f265141.b1fe4e8","name":"","pauseType":"delay","timeout":"2","timeoutUnits":"seconds","rate":"1","nbRateUnits":"1","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"x":840,"y":480,"wires":[["409aeeb4.586b28"]]}]

如果手动设置 msg.parts.id 和类似的东西,但它没有帮助。

这里以节点 FetchUser 的代码为例

if (typeof context.zaehler === 'undefined')
{
    context.zaehler=0;
}
context.zaehler++;
msg.payload = context.zaehler;
msg.parts = {};
msg.parts.id = msg._msgid;
msg.parts.index = 0;
msg.parts.count = 2;
return msg;

标签: node-red

解决方案


如果您将join节点设置为自动,这将起作用。之后,您可以将输出数组更改回带有匹配键的键控消息,因为您知道哪个路径具有哪个部件号。

[{"id":"7ded445b.56a8b4","type":"inject","z":"7a67e2ef.b4884c","name":"","topic":"","payload":"Trigger","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":110,"y":140,"wires":[["895ad6c4.4153c"]]},{"id":"895ad6c4.4153c","type":"function","z":"7a67e2ef.b4884c","name":"DataInputSimulation","func":"user=\"user@example.com\";\ncompany=\"ExampleCorp\";\nmsg.payload = {};\nmsg.payload.user = user;\nmsg.payload.company=company;\nreturn msg;","outputs":1,"noerr":0,"x":300,"y":140,"wires":[["d7c67e43.9e52c","ec3b0a63.574b88"]]},{"id":"d7c67e43.9e52c","type":"change","z":"7a67e2ef.b4884c","name":"FetchUser","rules":[{"t":"set","p":"payload","pt":"msg","to":"payload.user","tot":"msg"},{"t":"set","p":"topic","pt":"msg","to":"user","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":510,"y":120,"wires":[["31a50616.60f60a"]]},{"id":"ec3b0a63.574b88","type":"change","z":"7a67e2ef.b4884c","name":"FetchCompany","rules":[{"t":"set","p":"payload","pt":"msg","to":"payload.company","tot":"msg"},{"t":"set","p":"topic","pt":"msg","to":"company","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":520,"y":160,"wires":[["96a0ae8e.936d88"]]},{"id":"31a50616.60f60a","type":"function","z":"7a67e2ef.b4884c","name":"FetchUser","func":"if (typeof context.zaehler === 'undefined')\n{\n    context.zaehler=0;\n}\ncontext.zaehler++;\nmsg.payload = context.zaehler;\nmsg.parts = {};\nmsg.parts.id = msg._msgid;\nmsg.parts.index = 0;\nmsg.parts.count = 2;\nreturn msg;","outputs":1,"noerr":0,"x":710,"y":120,"wires":[["8d65dfdc.0c0038","777bde.99691c24"]]},{"id":"96a0ae8e.936d88","type":"function","z":"7a67e2ef.b4884c","name":"FetchCompany","func":"if (typeof context.zaehler === 'undefined')\n{\n    context.zaehler=0;\n}\ncontext.zaehler++;\nmsg.payload = context.zaehler;\nmsg.parts = {};\nmsg.parts.id = msg._msgid;\nmsg.parts.index = 1;\nmsg.parts.count = 2;\nreturn msg;","outputs":1,"noerr":0,"x":720,"y":160,"wires":[["7a299b8d.a4fd1c","4f5fd876.a42238"]]},{"id":"8d65dfdc.0c0038","type":"debug","z":"7a67e2ef.b4884c","name":"","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","x":910,"y":60,"wires":[]},{"id":"7a299b8d.a4fd1c","type":"debug","z":"7a67e2ef.b4884c","name":"","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","x":930,"y":140,"wires":[]},{"id":"777bde.99691c24","type":"join","z":"7a67e2ef.b4884c","name":"","mode":"auto","build":"object","property":"payload","propertyType":"msg","key":"topic","joiner":"\\n","joinerType":"str","accumulate":false,"timeout":"","count":"2","reduceRight":false,"reduceExp":"","reduceInit":"","reduceInitType":"num","reduceFixup":"","x":870,"y":260,"wires":[["bdaf6b65.8dbfc","852b8706.4d67"]]},{"id":"bdaf6b65.8dbfc","type":"debug","z":"7a67e2ef.b4884c","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","x":950,"y":360,"wires":[]},{"id":"4f5fd876.a42238","type":"delay","z":"7a67e2ef.b4884c","name":"","pauseType":"delay","timeout":"2","timeoutUnits":"seconds","rate":"1","nbRateUnits":"1","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"x":660,"y":300,"wires":[["777bde.99691c24"]]},{"id":"852b8706.4d67","type":"change","z":"7a67e2ef.b4884c","name":"","rules":[{"t":"move","p":"payload","pt":"msg","to":"temp","tot":"msg"},{"t":"move","p":"temp[0]","pt":"msg","to":"payload.user","tot":"msg"},{"t":"move","p":"temp[0]","pt":"msg","to":"payload.company","tot":"msg"},{"t":"delete","p":"temp","pt":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":700,"y":420,"wires":[["8f67784d.5de82"]]},{"id":"8f67784d.5de82","type":"debug","z":"7a67e2ef.b4884c","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","x":920,"y":440,"wires":[]}]

诀窍是从数组中移动总是访问元素0,因为它将元素从数组中弹出。


推荐阅读