Talend入門 (4)　～tMap～

##全体の目的
Talendの超簡単なサンプルジョブを作成して，ETLジョブ開発に必要なスキルを習得することが目的です。

##対象者
ETL / EAI技術者

##環境
|使用環境|バージョン|
|:----:|:------------------|
|OS|Windows10|
|Talend|7.1.1|	

##サンプル一覧
以下の順番で習得していきます

|#|内容|
|:----:|:------------------|
|1|[はじめてのTalend](https://qiita.com/airkoda/items/a837d3c5d851d98d2612)|
|2|[ファイルI/O](https://qiita.com/airkoda/items/1cd12c05c6136add7178)|
|3|[データベースI/O](https://qiita.com/airkoda/items/bc807c920c3adebad837)|
|**4**|**[tMap（今回）](https://qiita.com/airkoda/items/fa4a9c022b5d688698e0)**|
|5|[イテレータ](https://qiita.com/airkoda/items/404d2d65eff535b2126c)|
|6|[メタデータ](https://qiita.com/airkoda/items/4b42cf2a86f34abb6c87)|
|7|[Context変数](https://qiita.com/airkoda/items/42d294fca40b81aa20fb)|
|8|[Global Map](https://qiita.com/airkoda/items/1aba0d36905c755deeae)|
|9|[tHashInput/tHashOutput](https://qiita.com/airkoda/items/d9347865190f0f3ab180)|
|10|[エラーハンドリング](https://qiita.com/airkoda/items/85e7c49a9bf6a21db6d5)|
|11|[ロギング](https://qiita.com/y-fujioka-yoshiharu/items/e0280f34cff2e3d00bda)|
|12|[子ジョブ（ジョブのネスト）](https://qiita.com/y-fujioka-yoshiharu/items/04ea4bd74ded382cf03c)|
|13-1|[設定ファイル読み込みオリジナル版](https://qiita.com/airaotaku/items/92f114795108f25e6d0f)|
|13-2|[設定ファイル読み込みコンポ版](https://qiita.com/airyama/items/83c2bf9b2d51a79c3714)|
|14|[tJava](https://qiita.com/airkoda/items/4d81d76c36b6fcbd4d89)|

[サンプルコード（Talendプロジェクトデータ）](https://github.com/kd2air/qiita)

##今回の目的
tMapの使い方を覚える

##サンプルプログラム概要
従業員マスタに部門マスタを引き当てるプログラムを作ってみます。

##tMapを使った変換・加工 (Transform) 
2つの入力ソース（従業員マスタと部門マスタ）をどのように結合していくかを確認していきます。

### 入力ソース定義
それではサンプルジョブを作成していきましょう。
リポジトリの[ジョブ]を右クリックし[ジョブの作成]を選択します。
[名前]に"trans"と入力し[Finish]ボタンをクリックします。

![GS000098.png](https://qiita-image-store.s3.amazonaws.com/0/364565/859685c8-a5e3-381b-db7f-9420e141f675.png)

一つ目の入力ソースとして従業員マスタを想定した[tFixedFlowInput]コンポーネントを配置します。
![GS000099.png](https://qiita-image-store.s3.amazonaws.com/0/364565/d4d1cefa-5f0b-ba0d-f330-664e2e314e46.png)

[tFixedFlowInput]の[基本設定]の[スキーマ編集]ボタンを押下しカラム定義画面を開きます。
カラム名とタイプを以下のように設定します。

| 列      | カラム |  タイプ |
|:-----------------|:------------------|:------------------|
| 1列目    | id  | int|
| 2列目    | name  | String|
| 3列目    | department_code  | String|

![GS000100b.png](https://qiita-image-store.s3.amazonaws.com/0/364565/120ebf80-ee92-b64c-1e48-5ba48744a801.png)

[tFixedFlowInput]の[基本設定]のモード設定で[インラインコンテンツの使用]を選び以下設定します。

| 項目名              | 設定内容 |    説明  |
|:-----------------|:------------------|:------------------|
| フィールド区切り  | , | 入力データはcsv定義 |
| コンテンツ  | 下記emp.csvを張り付ける | csvファイルの代わりをここで定義できる |

```csv:emp.csv
1,kouda,02
2,mori,01
3,kubo,01
4,kimura,99
5,kinosita,99
```

![GS000101.png](https://qiita-image-store.s3.amazonaws.com/0/364565/c20b92b5-b63f-402d-1d2a-9cf7b30cc012.png)

二つ目の入力ソースとして部門マスタを想定した[tFixedFlowInput]コンポーネントを配置します。
![GS000102.png](https://qiita-image-store.s3.amazonaws.com/0/364565/8b6c74ac-89b5-3661-cd1e-a2d560a4e282.png)

[tFixedFlowInput]の[基本設定]の[スキーマ編集]ボタンを押下しカラム定義画面を開きます。
カラム名とタイプを以下のように設定します。

| 列      | カラム |  タイプ |
|:-----------------|:------------------|:------------------|
| 1列目    | department_code  | String|
| 2列目    | department_name  | String|

![GS000103.png](https://qiita-image-store.s3.amazonaws.com/0/364565/b3c49589-c4cf-6f3c-7f35-bd71eb571fa5.png)

[tFixedFlowInput]の[基本設定]のモード設定で[インラインコンテンツの使用]を選び以下設定します。

| 項目名              | 設定内容 |    説明  |
|:-----------------|:------------------|:------------------|
| フィールド区切り  | , | 入力データはcsv定義 |
| コンテンツ  | 下記department.csvを張り付ける | csvファイルの代わりをここで定義できる |

```csv:department.csv
01,sales
02,develop
03,planning
04,purchasing
05,general
06,accounting
```

![GS000105.png](https://qiita-image-store.s3.amazonaws.com/0/364565/9058e08b-079d-832f-fb5e-e6fc64688985.png)

### 外部結合
[tMap]コンポーネントを配置し従業員マスタとして定義した[tFixedFlowInput]をロウでつなぎます。
※最初につなぐことでメインロウという扱いになります。

![GS000106.png](https://qiita-image-store.s3.amazonaws.com/0/364565/2d9ba7ab-e817-8af9-bef7-35271006b249.png)

次に部門マスタとして定義した[tFixedFlowInput]を[tMap]にロウでつなぎます。
※2番目以降に接続したロウは全てルックアップロウという扱いになります。

![GS000107.png](https://qiita-image-store.s3.amazonaws.com/0/364565/55ddbd64-5314-2256-e704-6ea75f94bc50.png)

#### 結合設定
[tMap]コンポーネントをダブルクリックすることで編集画面が開きます。

![GS000108.png](https://qiita-image-store.s3.amazonaws.com/0/364565/6af8466b-c5f0-7b05-feca-d8d5736d9224.png)

row1のdepartment_codeをrow2のdepartment_codeの式キーにドラッグ＆ドロップします。
これでSQLでいうところのLEFT JOINした状態となります。

![GS000108c.png](https://qiita-image-store.s3.amazonaws.com/0/364565/7f1a95ae-3ecc-1aff-8b8f-0a9ccf18bae0.png)

[出力テーブルの追加]ボタン（画面の＋ボタン）をクリックします。

![GS000108d.png](https://qiita-image-store.s3.amazonaws.com/0/364565/d3f83ed9-5035-6f3f-c984-800c1b655502.png)

output追加ダイアログでout1という名前で新しいoutputを作成します。
![GS000109.png](https://qiita-image-store.s3.amazonaws.com/0/364565/bd6b4391-5759-205a-0f62-3147a25d0252.png)
![GS000110.png](https://qiita-image-store.s3.amazonaws.com/0/364565/5cb5b30f-9d7d-18d2-c1d6-6c3ca8e80716.png)

row1とrow2のColumnをそれぞれout1の式にドラッグ＆ドロップします。ここまで出来たらOKでダイアログを閉じます。
![GS000111a.png](https://qiita-image-store.s3.amazonaws.com/0/364565/7fbc6921-edbf-3a12-f132-8d2dbce33e47.png)

出力確認用の[tLogRow]を配置します。
[tLogRow]の[基本設定]にある[モード]もテーブルにしておきましょう。
![GS000112.png](https://qiita-image-store.s3.amazonaws.com/0/364565/35cb9a7c-fb09-4e94-ef28-3bdfd658d2ce.png)

[tMap]と[tLogRow]をつなぐには[tMap]で右クリックをして先ほど作成したout1を選択したうえでつなぎます。
![GS000112a.png](https://qiita-image-store.s3.amazonaws.com/0/364565/fb4f51f3-08cd-4639-f1fb-9472ada837c7.png)
![GS000113.png](https://qiita-image-store.s3.amazonaws.com/0/364565/ed567d5a-e2e3-6e79-5a08-497d0d195919.png)

設定は完了ですので実行してみます。
department_codeを結合キーとしてdepartment_nameの引き当てができました。
![GS000114.png](https://qiita-image-store.s3.amazonaws.com/0/364565/ec6457e5-370a-d282-4236-24e0f0fd1b8c.png)

### 内部結合
先ほどの結果だとdepartment_nameが**nullのデータ**ができていました。
今度は内部結合になるように設定してみましょう。

#### 結合設定
[tMap]コンポーネントをダブルクリックし編集画面が開きます。
row2にある赤枠で囲った[tMap settings]をクリックします。
![GS000114b.png](https://qiita-image-store.s3.amazonaws.com/0/364565/5c533033-030d-dfae-036d-fa01ee1f605f.png)

設定項目の[Join Model]を[Inner Join]に変更します。
![GS000118.png](https://qiita-image-store.s3.amazonaws.com/0/364565/14fa292b-9f72-d5f7-3726-2557c4bc952e.png)

これでSQLでいうところの内部結合（INNER JOIN）した状態となります。
![GS000119.png](https://qiita-image-store.s3.amazonaws.com/0/364565/8eae470b-c56c-4c14-d883-0d467195cbd3.png)

設定は完了ですので実行してみます。
department_nameの**引き当てができたデータのみ**が出力できました。
![GS000120.png](https://qiita-image-store.s3.amazonaws.com/0/364565/d4912cec-0501-ffe3-916c-80f12057e57f.png)

#### アンマッチデータの処理
引き当てができなかったデータを処理する方法を説明します。

[tMap]コンポーネントをダブルクリックし編集画面が開きます。
[出力テーブルの追加]ボタン（画面の＋ボタン）をクリックします。
![GS000122.png](https://qiita-image-store.s3.amazonaws.com/0/364565/15443073-b618-90a4-a587-e11d1b7815b9.png)

output追加ダイアログでout2という名前で新しいoutputを作成します。
![GS000123.png](https://qiita-image-store.s3.amazonaws.com/0/364565/e1776d47-5b02-36a6-68ae-4b7832b3ac33.png)
![GS000124.png](https://qiita-image-store.s3.amazonaws.com/0/364565/f34df916-e586-3980-1fab-bfe4ee5ec01f.png)

row1のColumnをそれぞれout2の式にドラッグ＆ドロップします。
※row2のdepartment_nameは引き当てできないので設定しません。
![GS000125b.png](https://qiita-image-store.s3.amazonaws.com/0/364565/7ef6dbcd-459e-2b4f-52a3-3d003dda4799.png)

out2にある赤枠で囲った[tMap settings]をクリックします。
![GS000130.png](https://qiita-image-store.s3.amazonaws.com/0/364565/1cd9d594-20e8-fcf7-a85d-4814f5a55012.png)

[Catch lookup inner join reject]をtrueに設定します。
ここまで出来たらOKでダイアログを閉じます。
![GS000132b.png](https://qiita-image-store.s3.amazonaws.com/0/364565/f5d4862f-59ef-391c-61ce-9768ec2f8ae0.png)

出力確認用の[tLogRow]を配置します。
[tLogRow]の[基本設定]にある[モード]もテーブルにしておきましょう。
![GS000127.png](https://qiita-image-store.s3.amazonaws.com/0/364565/fb98fa05-5a87-2502-5a64-799797d1a372.png)


[tMap]で右クリックをして先ほど作成したout2を[tLogRow]とつなぎます。
![GS000127a.png](https://qiita-image-store.s3.amazonaws.com/0/364565/d2da68c1-57f0-8f67-e189-977576c838e0.png)
![GS000128.png](https://qiita-image-store.s3.amazonaws.com/0/364565/6e167a5e-298e-259f-a06d-a73c92a95235.png)

それでは実行してみましょう。
内部結合できなかったデータを処理することができました。

```
.--+-----+---------------+---------------.
|               tLogRow_1                |
|=-+-----+---------------+--------------=|
|id|name |department_code|department_name|
|=-+-----+---------------+--------------=|
|1 |mori |01             |sales          |
|2 |kubo |01             |sales          |
|3 |kouda|02             |develop        |
'--+-----+---------------+---------------'

.--+--------+---------------.
|         tLogRow_2         |
|=-+--------+--------------=|
|id|name    |department_code|
|=-+--------+--------------=|
|4 |kimura  |99             |
|5 |kinosita|99             |
'--+--------+---------------'
```

### マッピング変数
最後にマッピング変数の使い方を見ておきましょう。

マッピング変数はtMapの処理において変数として処理を定義することで使いまわしができるものです。

[tMap]コンポーネントをダブルクリックし編集画面が開きます。
真ん中のVarのところにある[変数の追加]ボタン（画面の＋ボタン）をクリックします。
![GS000133.png](https://qiita-image-store.s3.amazonaws.com/0/364565/70562368-87cd-f5bb-83bb-02650570409f.png)

今回は従業員名を大文字変換した値を保持する変数を定義してみます。
式に以下コードを記入します。

| 式              |
|:-----------------|
| StringHandling.UPCASE(row1.name)  |

![GS000136.png](https://qiita-image-store.s3.amazonaws.com/0/364565/8fc0d1be-66c8-5a3e-72d2-ce22b3675a9f.png)

out1とout2に定義した変数var1をドラッグ＆ドロップし出力カラムとして追加します。ここまで出来たらOKでダイアログを閉じます。

![GS000137b.png](https://qiita-image-store.s3.amazonaws.com/0/364565/d43f49c7-b328-7d0b-28ca-115c136212a9.png)

「変更を反映しますか」ダイアログが表示された場合はYesで反映します。
![GS000138.png](https://qiita-image-store.s3.amazonaws.com/0/364565/f1456b90-a897-efe1-6f39-fc18cc334ce5.png)

それでは実行してみましょう。
従業員名を大文字変換したカラムを追加できました。

```
.--+-----+---------------+---------------+-----.
|                  tLogRow_1                   |
|=-+-----+---------------+---------------+----=|
|id|name |department_code|department_name|var1 |
|=-+-----+---------------+---------------+----=|
|1 |mori |01             |sales          |MORI |
|2 |kubo |01             |sales          |KUBO |
|3 |kouda|02             |develop        |KOUDA|
'--+-----+---------------+---------------+-----'

.--+--------+---------------+--------.
|             tLogRow_2              |
|=-+--------+---------------+-------=|
|id|name    |department_code|var1    |
|=-+--------+---------------+-------=|
|4 |kimura  |99             |KIMURA  |
|5 |kinosita|99             |KINOSITA|
'--+--------+---------------+--------'
```

##まとめ
今回はtMapの使い方を確認しました。
ETL処理でいうところのいわゆる Transform（変換・加工）の基本的な設定方法が分かってもらえたのではないでしょうか。
あらたに利用したコンポーネントと用途をおさらいしておきます。

- tMap
    - マップエディタ

毎度のことですが、ほんのさわりの部分だけを解説していますのでぜひここから深掘りしてみてください。

##次回以降
次回はイテレータをやっていきます。