2019年8月29日木曜日

LogicApps/Flow でコレクション間の差分を抽出する

Logic Apps や Flow では、配列やコレクションを扱う機会が非常に多く何かしらの操作をすることが多々あります。その中でもうまいやり方が見つかっていなかったコレクション間の差分(A と B の間で B のみに存在するデータ)を取得する方法で、フィルタ処理を利用したシンプルな方法が作成できましたので、メモ書きとして残します。


対象が配列の場合は、フィルタ処理のアクションを利用して簡単に指定できるのですが、コレクションの場合はそのままではフィルタ処理が行えません。そのため素直に処理を作成すると、ForEach を利用したループで 1 件ごとに存在するかチェックし、存在していなかったら変数に追加していく方法をとることも多いと思います。この形で要件は満たせるのですが、対象となるデータ件数が増えると飛躍的にアクション数と実行時間が増えてしまうのがネックです。特に Logic Apps の場合では、アクション数が増える=課金が増える ことに直結していますのでできる限りアクション数は押さえたい所です。

今回の全体的な処理の流れは次のようになります。

今回のサンプルデータとして、JSON 値を持つ配列を次のように作成しています。


A のコレクションには name という値に A, B, C, D, E と設定し、B のコレクションには A, B, C, E, F と設定し、差分が発生するように作成しています。A と B を比較して、A のみに存在する name = D となるものだけを取得してみます。

そのためにはフィルタ処理を利用するのが最善のため、比較対象となる項目だけを抽出して配列を作成します。一度ヘッダ情報のない CSV 作成を行うことで、配列に変換できるデータが作成できます。

このような形で比較項目だけに限定して抽出できたので、これを配列に変換します。

split 関数を利用して配列へ変換するのですが、その時は Logic Apps や Flow での悩みの種である改行コードが付いて回るので、uriComponent 関数を利用して変換した結果から、改行ごとに分割して配列を作成するように記述します。

split(uricomponent(body('AコレクションからCSVテーブルの作成')),'%0D%0A')

配列が作成できたので、ようやくフィルタ処理が行えます。対象となるのはコレクション B を指定し、フィルタ条件としては次のように設定します。

contains(outputs('Aコレクションから比較要素のみで配列化'), item().name)

上記の関数式の結果が False になれば、A コレクションには存在しない B コレクションだけのものと判断できます。このような形で処理を行うことで、コレクション間の差分をレコード数に関係なく 3 アクションで取得が可能です。contains 関数は対象が配列であれば、含む・含まないの判断が容易に行えますので、比較対象の値だけに絞った配列を作成することを活用してみてください。

0 件のコメント:

コメントを投稿