Node-REDでやり取りするJSONデータをSQLのように使えるAlaSQLノードを使ってみたメモです。
背景
Node-REDはノード間を msg というオブジェクトにぶら下がった payload というオブジェクトにデータを格納してやり取りします。ノード間でデータをやり取りしていく上で、データ加工が必要になるんですが、検索やソートがしやすいSQL的な書き方がしたくなることがあります。
もちろん、changeノードでJSONataしたり、Functionノードの中で、Array.matchであったり地道に処理したりもあるんですが、もうちょっとイイ感じにやりたい。
そんなとき、こんな会話で盛り上がりました。1月のことです。
うわーすごいですねこれw
— Tanaka Seigo (@1ft_seabass) January 29, 2020
ということで、AlaSQLノード
AlaSQLノードはこちらです。
node-red-contrib-alasql (node) – Node-RED
AlaSQLノードは AlaSQL.js を本体にしているもので、詳しい使い方は以下が参考になります。
SQLでできそうなことが、ある程度できそうですね。
余談ですが:最新のバージョン 2.0 を使いましょう
ここで少し注意です。リリースされた 2.0 を使いましょう。
実は msg.topic あるいは msg.query を元に動的にクエリを作る機能が、以前から実装されていたのに、Node-REDへバージョン反映されていなかったのをお願いしたのが、(2020/06現在)最近だからです。
Could you execute "npm publish" as v2.0.0 ? · Issue #29 · AlaSQL/node-red-contrib-alasql
このあたりのバージョンアップのお願いは、実は私がコミュニケーションして、開発者の人に更新してもらいました!やりとりがポジティブで楽しかった。
もちろん、今後更新がされれば、最新バージョンを追いかけるのがいいでしょう。
ということで使ってみる
「様々な年齢の5人のユーザーから20歳以上を検索してみる」ということをしてみましょう。
このようなフローです。インポートできる JSON データはこちらです。
[{"id":"4b1563b.551df9c","type":"alasql","z":"f5146fe6.90b9f","name":"SELECT * FROM ? WHERE age >= 20;","query":"SELECT * FROM ? WHERE age >= 20;","x":660,"y":1200,"wires":[["8f83ee8f.cb07a"]]},{"id":"8f83ee8f.cb07a","type":"debug","z":"f5146fe6.90b9f","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","x":930,"y":1200,"wires":[]},{"id":"2549e15d.d0eebe","type":"inject","z":"f5146fe6.90b9f","name":"データ","topic":"","payload":"[{\"name\":\"ユーザ1\",\"age\":15},{\"name\":\"ユーザ2\",\"age\":12},{\"name\":\"ユーザ3\",\"age\":20},{\"name\":\"ユーザ4\",\"age\":35},{\"name\":\"ユーザ5\",\"age\":60}]","payloadType":"json","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":370,"y":1200,"wires":[["4b1563b.551df9c"]]}]
inject ノード
inject ノードです。
このようなデータを流し込んでいます。
AlaSQLノード
AlaSQLノードです。
こちらでは SELECT * FROM ? WHERE age >= 20;
というSQLクエリを指定していて、ageという値をみて20歳以上を検索しています。 ?
というのが `msg.payloadP で来たデータを指しています。
動かしてみる
実際に、 inject ノードをクリックして動かしてみます。
このように、無事に20歳以上がソートされて、書いたSQLクエリ目論見通り取得することができました。
広がる可能性
AlaSQLノード、いいですよね。ここのところ、いろいろ使っていて気づきがあるのでメモしておきます。
- CREATE TABLE のようにテーブル作成をすると、Node-RED再起動するまでメモリに記録される模様
- つまり、Node-RED再起動するまで AlaSQLノード内共通でNode-REDのグローバル変数のように使えてテーブル名で呼び出せる
- DATETIMEのような型でも検索できて日付検索がやりやすかった
- SUM・COUNTも素直に動いた
- メモリを許す限りで動くため動作は高速
- Functionノードで JavaScriptでめっちゃ頑張るケースが減ってハッピー
- しかも、高速なのがうれしい。200件とか全然大丈夫。1000件も行けそうな雰囲気。
- 素の AlaSQL.js も Node.js で使ってみたくなる!
といった感じです。
より突っ込んだユースケースがあれば、またご紹介していきます。