Pentaho Data Integrationでよく使う変換機能10選

PDIでよく使うなと思う変換機能(ステップ)をまとめて紹介していきます。
なお、定数追加を含む文字列加工機能は色々あるので、それは別途紹介するとして、今回はそれ以外の機能に絞りました。

# 1. 選択/名前変更
Inputデータのフィールド名変更や型変更、不必要なフィールドの除去、フィールド順序の変更などを行うことができます。
様々なデータ加工を行い、無駄にフィールド(列)が多くなってしまった際の整理によく使用されます。
感覚的にはTransformationを作ると必ずひとつは使うと思います。
少々コストの高い処理なので使いすぎると処理が重くなるよと、Pentahoの中の人に以前聞いたことがありますので多用にはご注意ください。
後述するグループ化ステップでも不要なフィールドの削除はできるので、処理の中でグループ化(合計とか)を行う場合などは、そちらでフィールド整理してしまっても良いかもしれません。

以下のように「選択/名前変更」ステップを配置します。元データはデータグリッドステップを使用しています。
各設定を行ったあと、選択/名前変更ステップ上で右クリックして、プレビューを行うことで結果を確認することができます。
<img width="500" alt="pdi_1001.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/186651/75c3ebe7-66de-f879-b067-6e95e480719a.png">

データグリッドは、以下のような構造とデータになっています。
<img width="400" alt="pdi_1002.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/186651/e5796621-326e-4003-aace-27caa6b62360.png">
<img width="400" alt="pdi_1003.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/186651/cd368741-f5d8-c0b9-0591-ac2be50f9330.png">

【フィールドの除去とフィールド名の変更】
<img width="400" alt="pdi_1004.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/186651/c7124db1-f0fa-9cca-ce1f-fb3356a37b6c.png">
以下、結果です。
<img width="280" alt="pdi_1007.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/186651/fdb195f8-20eb-9e13-c436-4ded7173ce3a.png">

【フィールド順序の変更】
<img width="600" alt="pdi_1005.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/186651/6a0ef856-850e-d100-8449-fcbd131e5b2f.png">
以下、結果です。
<img width="280" alt="pdi_1006.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/186651/961bf597-b1cd-c0ee-aefa-be314b2da363.png">

【除去フィールド】
<img width="600" alt="pdi_1008.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/186651/eb631b3e-8456-7a9c-8a23-55286130e186.png">
選択フィールドと変わらないので結果は割愛します。
ちなみに選択フィールドで選択しているものを、除去フィールドで選択すると、結果的には削除されます。

【型変換】
<img width="600" alt="pdi_1009.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/186651/2e3ac949-e73c-1324-94b4-f95bea5bb744.png">
こちらも結果は割愛します。

# 2. ストリーム参照
データをキーにして別のデータとマッチング、必要なデータを取得する際に使用します。
基本的には結合処理と同じですが、Left Outerでマスタ情報を取得する処理ができるものと考えればよいかと思います。
具体的には、売上伝票等のトランザクションデータに商品マスタの商品名を追加するなどの場合に使用ができます。
(トランザクションデータは商品コードを持ち、商品マスタは商品コードと商品名やカラーなどを持っている想定です)
<img width="650" alt="pdi_101.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/186651/ffdbbdd5-5a22-c6d0-19d8-61fd748d876a.png">

トランザクションデータと商品マスタデータの中身は以下のような感じです。
<img width="600" alt="pdi_103.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/186651/864ddf80-a669-0796-db6c-988b830d9bf7.png">

以下のように設定を行います。
参照する側のデータ(ここでは商品マスタデータ)を指定して、トランザクションデータにあるitem_cdをキーに参照側データのnameとcolorを取得するというイメージです。
<img width="700" alt="pdi_206.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/186651/1d6641ff-255b-d23f-43f6-5b194d468332.png">
以下、結果です。
<img width="400" alt="pdi_107.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/186651/e32cac50-1ed6-a9f3-e38c-d9507b60f280.png">

# 3. 行整列
行整列ではソートを行うことができます。複数キーでの並び替えも可能です。
ストリーム参照で使用したTransformationに行整列ステップをつなげて説明していきます。
![pdi108.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/186651/56b0e885-0a17-2b7a-5836-a32cd58d4fb6.png)

ソート前のデータは以下のようになっております。
<img width="400" alt="pdi_109.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/186651/2fb6d0c4-95cb-2839-1427-fd653ff3591e.png">

ソート後の結果は以下のとおりです。
<img width="400" alt="pdi_110.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/186651/5e8d819e-1461-b699-9c9b-d01340724bcd.png">

# 4. グループ化
グループ化は、キーを指定して、そのキーごとのデータの合計や平均値の計算、MaxやMin値の取得、先頭や最後の値の取得などを行う際に使用します。
注意点としては、グループ化を行う前に事前にソートをしておく必要があることでしょうか。ソートせずに実行すると正しい結果が取得できません。
これも行整列で紹介したTransfromationの後ろにグループ化ステップをつなげて説明していきます。

まず、元データは以下のとおりです。
<img width="400" alt="pdi_115.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/186651/1eb87c59-3e5f-e636-059b-c4fe30fb7c19.png">

グループ化ステップの設定は以下のとおりです。
![pdi111.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/186651/6cbbcea8-f90e-68f4-dd19-24fb87f6a4f2.png)

OKで保存する際に、以下のようなメッセージが表示されます。
日本語的に何を言っているかよくわからないメッセージですが、これは事前にソートしてないと結果が正しくならないことがありますよ、ということを伝えようとしているものです。あまり深く考えずに了解しておきましょう。
<img width="450" alt="pdi_112.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/186651/5c4e815f-bf3c-a313-9ea4-c3882904d18c.png">

結果は以下のとおりです。
<img width="450" alt="pdi_113.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/186651/0754a119-61b0-2b06-11fb-716b65b75fcb.png">
item_cdをキーとして集計しているのでitem_cdでユニークになっています。
colorはitem_cdごとの最初の値を取得しており、以降は、最小値、最大値、合計、平均、tran_idの数が格納されています。

グループ化ステップで使用できる演算子は以下のとおりです。
<img width="400" alt="pdi_114.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/186651/f1f15aad-dcc5-cbbf-9199-0e92254ff2a1.png">

# 5. フィルター
フィルターでは条件を指定して、条件に合致したものとしなかったもので処理を変更する際に使用します。
今回は、以下のデータを使用して"item_cd = 1001"の条件でフィルターを実行したいと思います。
<img width="400" alt="pdi_125.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/186651/535e1485-2ddb-a719-54c5-d481d8645d8b.png">

フィルター設定は以下のとおりです。
![pdi116.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/186651/45afef63-bdc3-4b14-83d0-cff519656245.png)
フィルターステップのあとのホップ上に「チェック」マークと「X」マークのアイコンが付いていますが、フィルター条件に合致したデータは「チェック」マーク側の処理に流れ、合致しなかったデータは「X」マーク側へ流れて処理が継続されます。
よく使用されるケースとしては、やはりその名のとおりデータをフィルタしたいときで、処理条件に合うデータのみを抽出する場合が考えられます。
対象外となったデータを捨てたい場合は、ダミーステップを使用します。
ダミーステップは、何も処理を行わないステップなので、ダミーステップにつないで、その後別のステップにホップをつながなければそちらへ流れたデータはそこで破棄されます。
ダミーステップへつないで、ダミーステップ名前を「対象外データ破棄」とかつけておくことで、Transformationの可読性を上げることもできます。

以下、結果です。
<img width="600" alt="pdi_119.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/186651/7862c58a-d34d-da01-1f55-6e28910beed7.png">

なお、処理を分けずに以下のようにすると、Trueのデータのみ後続処理に流すこともできます。
![pdi124.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/186651/166c2bfe-eb15-a80d-295e-69a9a7949a79.png)

今回は全体的な説明のため単純な式でのフィルターをご紹介しましたが、複数式のANDやOR、NOT、IFの入れ子なども作ることができます。この辺はまた別の記事にしようかと思います。

# 6. スイッチ/ケース
フィルターでは条件式の結果でTrueかFalseの二つの処理へデータを流すことができましたが、スイッチ/ケースでは条件に従い、3つ以上の処理へデータを流すことができます。
今回もフィルターの説明と同じデータを使用し、そのなかのitem_cdを使用して処理を分ける設定の説明をしたいと思います。
使用する元データです。
<img width="400" alt="pdi_126.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/186651/46deb6ce-6377-9c88-cc7d-c79e650821ff.png">

次にスイッチ/ケースステップを配置して、設定を行います。
![pdi127.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/186651/9c39a805-623a-e160-702b-c79666f98ed4.png)
ここまでで、条件指定はできましたので、次に各条件に合致したときに実行される処理をダミーステップで作成しておきます。
<img width="400" alt="pdi_129.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/186651/87426838-1187-8985-3dc6-caed1b211f1a.png">
スイッチ/ケースから各ダミーステップにホップを接続していきます。その際にどの条件を使用するのかを確認されるので、以下のように設定していってください。
<img width="600" alt="pdi_130.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/186651/68fcc8a4-397c-9c75-86f2-d2aae0989995.png">
すべて接続したあとに、スイッチ/ケースの設定を確認して、以下のようになっていればOKです。結果は割愛します。
<img width="400" alt="pdi_131.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/186651/2f12fc1d-d345-4b7c-fce3-e8ee5def7dfa.png">

# 7. Join
Joinはその名の通り、二つのデータをキーを指定して結合し、一つのデータセットにするものです。
Joinに関してはいくつか機能が提供されていますが、今回は「マージ結合」をご紹介します。
以下のようにTransformationの処理を作成します。
![pdi136.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/186651/69ddfa8f-5491-477c-13da-af9604f51b82.png)
データグリッドを２つ置き、それぞれテストデータを設定したらJoinで使用するキー項目でソートを行い、最後にマージ結合ステップを置いてつなげます。

次に、マージ結合の設定を行います。
<img width="300" alt="pdi_137.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/186651/b175e723-e722-7155-345d-ef3998aa097e.png">
結合1のステップ名はLeftTable、結合2のステップ名はRightTableとなり、フィールドでそれぞれのキー項目を指定します。
結合タイプは、INNER、LEFT OUTER、RIGHT OUTER、FULL OUTERが選べます。
また結合時にLeftとRightTableデータに同じフィールド(カラム)が存在した場合は、RightTable側のフィールド名がリネームされます(_1などがフィールド名の後ろに付く)。
それぞれの結果は以下のとおりです。

【INNERの結果】
InnerJoinなので、LeftTableとRightTableの両方にキーが存在したデータのみ出力されます。
<img width="300" alt="pdi_138.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/186651/dd60f251-9ed2-4ed6-3a1c-dfed461c36ad.png">

【LEFT OUTER】
LeftTableのデータはすべて出力し、さらにRightTableからはキーと結合できたデータだけ取得します。取得できなかったデータはNULLが設定されます。
<img width="300" alt="pdi_139.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/186651/4fa0349c-6454-6a8a-685d-45d8827c00cd.png">

【RIGHT OUTER】
Left Outerとは逆で、RightTable側がすべて出力され、LeftTable側からキーで取得できたデータが出力されます。取得できなった箇所はNULLが設定されます。
<img width="300" alt="pdi_140.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/186651/6ede551c-6736-13d3-4bbf-10a6068d06d7.png">

【FULL OUTER】
簡単に言えば直積結合です。
LeftTableとRightTableのデータのすべての組み合わせのデータを作成します。
<img width="300" alt="pdi_141.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/186651/ecc35d49-ec47-101b-a6ce-902ef592018d.png">

# 8. ストリーム結合
Joinのようにキーで結合するのではなく、2つのデータを上下にくっつけてくれる処理です。
SQLでいうところのUnion Allです。
結合するデータは同じフィールド構造でなくてはいけません(違うフィールド名があるとエラーになります)。
以下のように設定していきます。
![pdi144.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/186651/40c9707a-b99a-da00-659c-05a37dadc1d5.png)
続いて、ストリーム結合の設定を行います。
設定は簡単で、上にくるデータと下にくるデータをそれぞれ指定するだけです。
以下の例では、「ダミー（何もしない）1」のデータを上に追加して、その下に「ダミー（何もしない）2」のデータを追加するという動作になります。
<img width="300" alt="pdi_145.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/186651/bead97bc-a5bd-d171-01af-c4298d56c508.png">
結果は以下のとおりです(同じデータにしてしまったのでわかりにくいですが、データが結合されていることはわかるかと思います)。
<img width="300" alt="pdi_146.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/186651/5f8e9345-5338-5d68-6396-fcab48563212.png">

# 9. 数式
少々込み入ったデータ加工などを行う場合、どうしてもPDIが持つ基本的な機能では足らなくなる場合があります。
また、基本機能でETL処理を組むとどうしても手数が増えて処理内容が冗長になってしまい、処理の流れが見えづらくなってしまうような場合もあります。
そういった場合に自分でロジックを組むことができるのが数式ステップです。イメージ的にはExcel関数に近いです。
PDIはデータをストリーム形式で1行ずつ処理していきますので、同じ行のなかのデータを使用した条件処理やデータ加工などで役に立ちます。

今回は以下のテストデータを使用して、varが1000より小さいときは"対象外"、大きいときは"対象"というデータを設定する処理を作成したいと思います。追加するデータは、新しくflgというフィールドを作成して、そこに設定します。
<img width="300" alt="pdi_147.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/186651/dd25aa1e-d100-0d4a-7279-734f2432cbc5.png">

テストデータを数式ステップをつなげます。
<img width="500" alt="pdi_154.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/186651/424a40da-82c8-433a-652a-d22922eb82e1.png">

次に数式の設定を行います。
![pdi152.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/186651/046de7d3-9056-ab34-b0b1-955365ac9bad.png)
まず新しいフィールドにflgを追加して、データタイプをStringにしておきます。
次に、数式設定が空ですが、その空の場所をクリックすると数式を入力するためのWindowが表示されますので、ここで数式を設定していきます。
式のなかでフィールドの値を使用したい場合は、"[フィールド名]"を指定します。今回はvarを使いたかったので[var]と設定しています。
具体的には、「IF([var];"対象外";"対象")」と設定します。

結果は以下のとおりです。
flgフィールドに対象、対象外とデータが追加されていることが確認できます。
<img width="300" alt="pdi_147.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/186651/6d4033bc-5b7a-8ba6-570d-e8a54f2661b4.png">

【フィルターで作成した場合】
上記では数式ステップを使用しましたが、フィルター機能を使用して同じ処理を作成することも可能です。
その場合は、少々冗長的なフローとなります。参考までに載せておきますので、違いだけご確認いただければと思います。
![pdi255.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/186651/adff8b95-2f26-69fa-62ec-3aa52d7524d5.png)
詳細は割愛しますが、数式ステップを使用したほうがスッキリしたフローになります。

# 10. ダミー
フィルターステップなどでも使用していますが、ダミーステップは何もしないステップです。
データを受け取るとそのまま後続処理へデータを流していきますし、後続処理が設定されていない場合は、そこで処理が終わります(受け取ったデータは渡す先が無いので破棄されます)。
そのため、一番ある使われ方としては、フィルターやスイッチ/ケース後に、処理対象外となったデータを破棄するためにつないでおくというものになります。
![pdi156.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/186651/99c689cc-77d4-7ac6-5715-39d77abb2058.png)

あとは、フローが混み合ってきてホップが重なってしまい見にくくなったときなどに、ダミーステップを経由させてホップを整理して見やすくするなどにも使用できますし、なにもせずにデータを受け渡してくれるものと考えればいろいろと使える場面もあるかと思いますので、覚えておくと役立つことがあるかもしれません。

# まとめ
個人的によく使うステップを中心に10の機能をご紹介しました。
別の記事になっているInputとOutputの設定と、今回の変換機能を使用することで、かなりいろいろなデータ加工の処理が作成できるかと思います。
また、最初にも記載しましたが文字列加工の機能は今回の紹介には含めていないので、別途記事を書こうかと思っております。
あとは、もっと具体的なケースごとの記事も書いていく予定です。

少々長くなってしまいましたが、今回は以上です！