S-JIS[2013-11-10/2016-02-11] 変更履歴

Asakusa Framework マスター結合演算子

Asakusa FrameworkOperator DSLのマスター結合演算子(@MasterJoin)のメモ。


概要

マスター結合演算子は、レコードに合致するマスターレコードと結合した新しいデータモデルを生成する演算子。
性能特性はJoin(旧ドキュメントではReduce、最適化によってはMap)。[/2016-02-11]

入力
ポート数
入力データモデル
の制約
イメージ 出力
ポート数
出力データモデル
の制約
入力1レコード
に対する
出力レコード数
2 master (マスター) 2 joined 結合モデル txの1レコードに対し
joinedかmissedの
どちらかに1レコード。
tx   missed txと同じ
データモデル

トランザクション(明細データ)レコード(の指定したキー)に合致するマスターレコードが存在したら、そのトランザクションレコード とマスターレコードを結合したデータをjoinedに出力する。
存在しなければトランザクションレコードをmissedに出力する。

joinedのデータモデルは、DMDLで結合モデルとして定義する必要がある。

逆に、結合モデルを元の2つのデータモデルに分解するには分割演算子(@Split)を使う。


合致するマスターが存在するかどうかを確認するだけの場合はマスター確認演算子(@MasterCheck)を使う。
(マスターデータは出力しないが)結合したマスターデータの内容に応じて処理を分岐したい場合はマスター分岐演算子(@MasterBranch)を使う。
(マスターデータは出力しないが)結合したマスターデータの値によってトランザクションレコードの値を変更したい場合はマスターつき更新演算子(@MasterJoinUpdate)を使う。


hoge_transactionとhoge_masterを結合したデータを出力する例。
(この図はToad Editorを用いて作っています)

入力データ例   出力データ例
master
hoge_master
id name group
a apple 1
b orange 2
c toy 100
d game 101
e other 900
f other2 999
joined
joined_hoge
id name group date master_id value
a apple 1 2013-11-29 a 123
b orange 2 2013-11-29 b 456
d game 101 2013-11-29 d 789
e other 900 2013-11-29 e 111
tx
hoge_transaction
date master_id value
2013-11-29 a 123
2013-11-29 b 456
2013-11-29 d 789
2013-11-29 e 111
2013-11-29 z 222
missed
hoge_transaction
date master_id value
2013-11-29 z 222

example.dmdl(DMDL):

hoge_master = {

    id : TEXT;

    name : TEXT;
};

hoge_transaction = {

    date : DATE;

    master_id : TEXT;

    value : LONG;
};

joined joined_hoge = hoge_master % id + hoge_transaction % master_id;

マスター結合演算子で結合した結果を表すデータモデルは、結合モデル(joinedを先頭に付けたデータモデル)にする必要がある。
結合モデルの書き方

ExampleOperator.java(Operator DSL):

import com.asakusafw.vocabulary.operator.MasterJoin;

import com.example.modelgen.dmdl.model.HogeMaster;
import com.example.modelgen.dmdl.model.HogeTransaction;
import com.example.modelgen.dmdl.model.JoinedHoge;
public abstract class ExampleOperator {

	/**
	 * HogeMasterとHogeTransactionを結合する
	 * 
	 * @param master
	 *         マスタデータ
	 * @param tx
	 *         トランザクションデータ
	 * @return 結合結果
	 */
	@MasterJoin
	public abstract JoinedHoge join(HogeMaster master, HogeTransaction tx);
}

マスター結合演算子は抽象メソッドとして定義する。
第1引数でマスターとなるデータモデル、第2引数でトランザクション(明細)となるデータモデルを指定する。
戻り値の型は結合結果のデータモデル(結合モデル)を指定する。

他の結合系演算子(マスター確認演算子等)では@Keyアノテーションで結合キーを指定するが、
マスター結合演算子では結合モデルで結合キーを指定しているので、Operatorクラスではキーを指定する必要は無い。

ExampleJob.java(Flow DSL):

import com.example.modelgen.dmdl.model.HogeMaster;
import com.example.modelgen.dmdl.model.HogeTransaction;

import com.example.operator.ExampleOperatorFactory;
import com.example.operator.ExampleOperatorFactory.Join;
	private final In<HogeMaster>      master;
	private final In<HogeTransaction> detail;

	private final Out<JoinedHoge>      out1;
	private final Out<HogeTransaction> out2;
	@Override
	public void describe() {
		ExampleOperatorFactory operators = new ExampleOperatorFactory();

		// マスター結合
		Join join = masterOperator.join(this.master, this.detail);

		this.out1.add(join.joined);
		this.out2.add(join.missed);
	}

Flow DSLでは、自分が作ったOperatorのFactoryクラス(AsakusaFWのコンパイラーによって生成される)を使用する。
メソッド名はOperatorクラスに書いたメソッド名と同じ。
戻り値の型はAsakusaFWのコンパイラーによって生成されたクラス。(メソッド名を先頭が大文字のキャメルケースに変換したもの)
メソッドの引数は第1引数がマスターデータ、第2引数がトランザクション(明細)データ。
出力ポートの名前のデフォルトはjoinedとmissed。

出力ポート名を変えたい場合は@MasterJoinアノテーションで指定できる。

	@MasterJoin(joinedPort = "joined", missedPort = "missed")

単体テスト

マスター結合演算子は抽象メソッドなので、(Operatorクラスにプログラマーがメソッド本体を実装していないので)Operatorの単体テストを実装する必要は無い。


結合モデルの書き方

マスター結合演算子で結合した結果を表すデータモデルは、DMDL上で結合モデルとして定義しておく必要がある。

説明
joined hoge = 〜;
モデル名の前に「joined」を付ける。
joined hoge = master % id + detail % master_id;
結合元を「結合元データモデル % 結合キー」で表し、2つの結合元を「+」でつなぐ。
joined hoge =
master % key1, key2 +
detail % master_key1, master_key2;
結合キーが複数項目の場合は、カンマ区切りで指定する。
慣れないと「+」が何をつないでいるのか分かりにくい(苦笑)
joined hoge =
master -> {
    id   -> id;
    name -> name;
} % id +
detail -> {
    master_id -> master_id;
    value     -> value;
} % master_id;
結合元のプロパティーの一部だけを出力したい場合は、
波括弧でくくって必要なプロパティーを記述する。
joined hoge =
master -> {
    id   -> id;
    name -> name;
} % id +
detail -> {
    master_id -> id;
    value     -> value;
} % id;
プロパティーの「->」の右側は結合モデルでのプロパティー名を表す。
(結合元と異なるプロパティー名を付けることが出来る)

キー項目のプロパティー名は別々の結合元であれば同じ名前を付けることが出来る。
(キー項目以外では異なる結合元でも同じプロパティー名を付けることは出来ない)

「%」の後ろに使うのは、結合モデルでのプロパティー名(「->」の右側で指定した名前)。

類似

マスター結合演算子は、SQLのJOINに相当する。

INSERT INTO joined
SELECT * FROM tx INNER JOIN master ON master.id = tx.master_id;
INSERT INTO missed
SELECT tx.* FROM tx LEFT JOIN master ON master.id = tx.master_id
WHERE master.id IS NULL;

Operator DSLへ戻る / AsakusaFW目次へ戻る / 技術メモへ戻る
メールの送信先:ひしだま