Asakusa Framework Advent Calendar 2013の22日目です。
AsakusaFWの演算子は23種類あります。中にはほとんど使わないものもあるので実質的にはもう少し減りますが。
AsakusaFWのアドベントカレンダーを始めた時は参加者があまり居ないだろうと思っていたので、およそ1日1演算子でブログを書いていけばちょうど良いと想定していたんですが、ありがたいことに予想に反して多くの人に参加していただき(笑)、気が付いたら演算子に全く触れることが出来ませんでした(爆)
という訳で、演算子擬人化をする人向けに演算子をまとめて紹介したいと思います。
まずはフロー制御系の中から、分岐演算子(@Branch)。愛称はブランちゃんで決定w
条件に応じてデータの出力先を振り分ける演算子です。郵便局で手紙を振り分ける作業に似ているような気がしますね。
次は合流演算子(confluent)。
複数の同一データモデルのデータを1つにまとめます。SQLのUNIONみたいなものです。
フロー制御系の最後は複製演算子。
出力されたデータを複数個所で使用するために複製する、というイメージですが。
これはAsakusaFWとして論理上定義されているけれども、DSLとしてコーディングに使うものは用意されていません。幻のキャラですね。NO IMAGEでいいでしょう。
続いて、データ操作系。
まずは更新演算子(@Update)。
レコード内の項目を使って(演算して)別の項目の値を設定するときに使います。入力データモデルと出力データモデルは同一となります。
変換演算子(@Convert)は、別のデータモデルに変換したいときに使います。
データの移送をいちいち書かないといけないですが、逆に言えば演算を行うことも出来ます。
拡張演算子(extend)・射影演算子(project)・再構築演算子(restructure)も別のデータモデルに変換する演算子です。
入力と出力のデータモデル間で同名プロパティーであれば自動的に移送してくれます。
特殊なケースで楽をする為の演算子群ですね。Convertはデータ移送をいちいち書かないといけないので。
拡張はプロパティーが増える、射影はプロパティーが減る、再構築はプロパティーが増減するときに使用します。
いわば同一キャラで装備が異なる感じです。
データ操作系の最後は抽出演算子(@Extract)。
1レコードの入力に対して複数種類データモデル・複数レコードを出力できます。
性能特性がMapの演算子の中では最強です。
結合系では、マスター確認演算子(@MasterCheck)・マスター結合演算子(@MasterJoin)・マスター分岐演算子(@MasterBranch)・マスターつき更新演算子(@MasterJoinUpdate)はひとまとめでいいでしょう。
2つの入力(マスターデータとトランザクションデータ)をキーで結合するところは全て同じです。
出力内容がそれぞれ異なるので、どういう出力が欲しいのかに応じて使い分けます。
敵の特性に応じて武器を持ち替える感じですね。
MasterCheckはマスターが存在するかどうかを確認する小手調べ。
MasterBranchはマスターの内容に応じて振り分ける。
MasterJoinUpdateはマスターの内容を使ってトランザクションデータを書き換える。
MasterJoinはマスターとトランザクションデータを結合した新しいデータを生成する。
分割演算子(@Split)は、MasterJoinの裏の姿です。
MasterJoinによって生成された結合モデルのデータを、元の(結合前の)2種類のデータモデルに分離します。
グループ結合演算子(@CoGroup)はAsakusaFWの全演算子の中で最強です。最終秘密兵器です。
これさえあれば何でも出来る反面、最適化されづらいというデメリットがあります。
ゴテゴテに武器を装備できるが小回りが利かない感じでしょうか。なるべく登場させないようにしましょう。
次は集計系。
集計といえばまずは単純集計演算子(@Summarize)です。
SQLのGROUP BYによるSUM・COUNT・MIN・MAXに当たる集計が出来ます。とってもオーソドックス(笑)
関数型プログラミングが得意な人にとっては、畳み込み演算子(@Fold)も馴染み易いでしょう。
グループ整列演算子(@GroupSort)は、複数のレコードにまたがった処理を行うことができます。その際に入力データをソートすることも出来るので、整列(sort)という名が付いているのでしょう。
ちなみに、演算子擬人化する人向けの裏設定ですが、GroupSortはCoGroupが変装した姿です。AsakusaFW内部では、GroupSortは“入力ポートが1つしかないCoGroup”です。
残りは特殊系。
フロー演算子(FlowPart)は演算子群をまとめて1つの演算子として扱えるようにするものです。要するにサブルーチンを作るイメージです。
代表役というかまとめ役というか。ワンピースのカポネの能力が近いかなぁ(爆)
チェックポイント演算子(checkpoint)は普通は使わないでしょう。
AsakusaFWはHadoopのMapReduceジョブを作る際に複数の演算子を1つのMapReduceジョブにまとめる最適化を行いますが、checkpointがあるとそこで必ずMapReduceジョブが終わりになります(ジョブが分割されます)。
役立たずのように見えますが、何か特別な使い道があるのかもしれません。
ロギング演算子(@Logging)はデバッグ用です。
そこを通過するデータをログファイルに出力します。書記みたいな感じ?
最近のAsakusaFWではトレース機能が実装されつつあるので、Loggingの出番は減っていくでしょう。
空演算子(empty)と停止演算子(stop)は双子みたいな感じですね。
emptyは0件入力データを生成します。入力データが不要なポートに使用します。
stopは出力データが不要な場合の出力先として使用します。何でも食べちゃう腹ペコキャラ?
真面目な話に戻りますが、実際にFlow DSLを書こう(設計しよう)としたら、どの演算子を使えばよいか?というのは悩ましいところでしょう。
基本的には、各演算子の入力・出力に着目します。
抽出(Extract)とグループ結合(CoGroup)は最後の手段として、最初は選択肢から外します。その上で、
- 入力ポート数が1つでいいのか、2つを結合するのか。
- 1レコードずつ処理すればいいのか、前後のレコードも見たいのか。
- 出力は入力1レコードにつき1レコードでいいのか、複数レコード出力したいのか。
といった観点で見ていけば、使える演算子は限られてくると思います。