コレクションの要素の処理:page-support-status: eolScheduled

For-Each コンポーネントまたは Parallel For-Each コンポーネントのインスタンスにペイロードで渡すコレクションの要素を処理できます。各コンポーネントでスコープが設定されます。このスコープ内で他の種別のコンポーネントのほか、コネクタやモジュールを追加して各要素を処理できます。

2 つの簡単な例: For-Each の使用例と Parallel For-Each の使用例
Figure 1. For Each コンポーネントと Parallel For Each コンポーネントでは、コレクションの要素を処理するためのスコープが設定されます。
1 この例の For-Each コンポーネントでは、各要素をデータベースに 1 つずつ挿入します。各要素は、おそらく SQL INSERT ステートメントで使用できる文字列です。
2 この例の Parallel For-Each コンポーネントでは、各要素を Set Payload コンポーネントに送信し、そのコンポーネントで式を使用して要素を変更し、フローのペイロードに追加します。

どちらの種別のコンポーネントでも、あらゆるコレクションを処理できます。

For-Each コンポーネントでデータを処理してフローを続行する方法

For-Each コンポーネントは、コレクションの各要素を順次処理した後、For-Each コンポーネントに渡された元のペイロードを使用してフローを続行するために使用されます。

For-Each コンポーネントで実行されるアクションを示している図
Figure 2. 次の図は、For-Each コンポーネントを使用しているフローを表しています。角丸長方形はカードです。
1 あるカードでフローのペイロードを For-Each コンポーネントに渡します。ペイロードは要素のコレクションで構成されます。
2 For Each コンポーネントはコレクションを個別の要素に分割します。次に、スコープ内にある最初のコンポーネント、コネクタ、またはモジュールに各要素を順次送信します。各要素はスコープ内のペイロードとして処理されます。このため、スコープ内のコネクタが ​payload​ に対してアクションを実行したり、スクリプトを使用して ​payload​ を処理したりするように設定されている場合、ペイロードは、For-Each コンポーネントで受け取ったペイロードではなく、そのコンポーネントで処理している要素になります。
3 最後の要素が処理されると、For-Each コンポーネントは、フローの前のカードから受け取ったペイロードを次のカードに渡します。
4 フローの次のカードは For-Each コンポーネントが受け取ったペイロードと同じペイロードを受け取り、フローが続行されます。

Parallel For-Each コンポーネントでデータを処理してフローを続行する方法

Parallel For-Each コンポーネントは、コレクションの各要素を処理した後、結果をフローの次のカードに渡すために使用されます。

Parallel For-Each コンポーネントで実行されるアクションを示している図
Figure 3. 次の図は、Parallel For-Each コンポーネントを使用しているフローを表しています。角丸長方形はカードです。
1 あるカードでフローのペイロードを Parallel For-Each コンポーネントに渡します。ペイロードは要素のコレクションで構成されます。
2 Parallel For-Each コンポーネントはコレクションを個別の要素に分割します。次に、スコープ内にある最初のコンポーネント、コネクタ、またはモジュールに要素を同時に送信します。一度に処理する要素の最大数を指定できます。各要素はスコープ内のペイロードとして処理されます。このため、スコープ内のコネクタが ​payload​ に対してアクションを実行したり、スクリプトを使用して ​payload​ を処理したりするように設定されている場合、ペイロードは、Parallel For-Each コンポーネントで受け取ったペイロードではなく、そのコンポーネントで処理している要素になります。
3 すべての要素が処理されると、Parallel For-Each コンポーネントは、そのスコープ内で実行された処理の結果を集約して渡します。この結果により、フローの次のカードに渡されるペイロードが形成されます。
4 フローの次のカードは Parallel For-Each コンポーネントから結果を受け取り、フローが続行されます。

結果の順序は、元のペイロード内の要素の順序に対応します。たとえば、Parallel For-Each コンポーネントに渡されるペイロードが ​["Apple","Banana","Cherry"]​ であるとします。コンポーネントのスコープ内に、各要素を個別のコンポーネントとして処理する Set Payload コンポーネントがあります。Set Payload コンポーネントは DataWeave 式 ​payload ++ '-result'​ を使用して各ペイロードを処理します。Parallel For-Each コンポーネントは結果 ​["Apple-result","Banana-result","Cherry-result"]​ をフローの次のカードに渡します。

Parallel For-Each コンポーネントのスコープ内では、各要素の処理順序が、コレクションに含まれている各要素の順序であることは保証されません。したがって、いずれかのコネクタが特定の順序で要素を要求する場合 (たとえば、Database Connector を使用して特定の順序でデータベーステーブルを更新する場合)、代わりに For-Each コンポーネントを使用する必要があります。

また、Parallel For-Each コンポーネントのスコープ内で接続する API またはサービスに、許容される同時接続数の制限があるかどうかに注意する必要があります。ある場合、Parallel For-Each コンポーネントの最大同時プロセス数を指定する必要があります。

一括処理

For-Each コンポーネントを使用すると、コレクションをバッチに分割することで処理時間を短縮できます。各バッチは、個別の Mule メッセージとして処理されます。たとえば、コレクションに 200 個の要素があり、[Batch Size (バッチサイズ)] を 50 に設定すると、For Each コンポーネントは 50 個の要素から成る 4 つのバッチをそれぞれ個別の Mule メッセージとして反復処理します。

一括処理は Parallel For-Each コンポーネントではサポートされません。

変数

For Each コンポーネント内の各反復で、前の反復で使用した変数を使用できます。1 つの要素の処理中に作成された新しい変数や、既存の変数に加えられた変更は、別の要素の処理中に参照できます。変数へのこれらの変更は、引き続き For-Each スコープの外部で使用できます。

たとえば、For-Each コンポーネントのスコープの直前で Set Variable コンポーネントを使用するとします。Set Variable コンポーネント内で変数 ​NumOfElements​ を 0 に設定します。次に、For-Each スコープ内で Set Variable コンポーネントを使用して、同じ変数を使用します。このコンポーネントでは、コールされるたびに値を 1 ずつ増加する DataWeave スクリプトが指定されています。処理されるコレクションの別の要素を For-Each コンポーネントが送信するたびに、値が増加して ​NumOfElements​ に保存されます。すべての要素が処理されると、​NumOfElements​ の値は、コレクションに含まれていた要素の数になります。この値をフローの後続のカードが For-Each スコープの外部で使用できます。

Parallel For-Each コンポーネントの場合、スコープに入る変数の値は、各変数の処理の開始時点では同じです。1 つの要素の処理中に作成された新しい変数や、既存の変数の変更は、別の要素の処理中に参照できません。また、Parallel For-Each コンポーネントのスコープ内での変数の変更は、フローの後続のカードで使用できません。

たとえば、前述の例と同様に、Parallel For-Each コンポーネントのスコープの直前で Set Variable コンポーネントを使用するとします。Set Variable コンポーネント内で変数 ​NumOfElements​ を 0 に設定します。次に、Parallel For-Each スコープ内で Set Variable コンポーネントを使用して、同じ変数を使用します。このコンポーネントでは、コールされるたびに値を 1 ずつ増加する DataWeave スクリプトが指定されています。コンポーネントにより実行される各並列プロセスで、​NumOfElements​ が到達する最高値は 1 です。また、フローの後続のカードで ​NumOfElements​ を使用している場合、Parallel For-Each コンポーネントでコレクションの処理が終了した後、その初期値は 0 になります。これは、Parallel For-Each コンポーネントの開始前の値と同じです。

エラー処理

For Each コンポーネントと Parallel For Each コンポーネントでは、要素が原因でスコープ内のコンポーネント、コネクタ、またはモジュールが例外をスローした場合、コレクションの処理が停止します。また、Parallel For-Each コンポーネントでは、並列プロセスのいずれかがシステムへの開かれた接続を待機している間にタイムアウトした場合、コレクションの処理が停止します。並列プロセスで待機できる最大時間を設定できます。

例外が原因でコレクションの処理が停止した場合、Flow Designer では、例外をスローしたカードに赤の円が表示されます。タイムアウトが原因でコレクションの処理が停止した場合、Flow Designer では、Parallel For-Each コンポーネントのカードに赤の円が表示されます。​[Logs (ログ)]​ ペインを開くと、エラーメッセージを参照できます。

For-Each コンポーネントの設定

このコンポーネントを設定する場合、以下の項目に値を指定する必要があります。

Collection (コレクション)

Java コレクション、オブジェクト配列、マップ、または DOM ノードを返す式。デフォルト値は ​payload​ です。

Batch Size (バッチサイズ)

指定された数の要素のサブコレクションにコレクションを分割します。たとえば、コレクションに 200 個の要素があり、バッチサイズを 50 個の要素に設定すると、コンポーネントは 50 個の要素から成る 4 つのバッチを処理します。

Root Message Variable Name (ルートメッセージ変数名)

フローの前のカードから For-Each コンポーネントに渡されたメッセージ全体 (ペイロード、変数、および属性) を保存する変数の名前。

Counter Variable Name (カウンター変数名)

処理中の要素のインデックスを保存する変数の名前、たとえば、コレクションが ​['a','b','c']​ の場合、​a​ のインデックスは 0、​b​ のインデックスは 1、​c​ のインデックスは 2 です。For-Each コンポーネントで 2 番目の要素を処理している場合、変数の値は 1 です。

Parallel For-Each コンポーネントの設定

このコンポーネントを設定する場合、以下の項目に値を指定する必要があります。

Collection (コレクション)

並列で処理する部分のコレクションを定義する式を指定します。デフォルト値は ​payload​ です。

Timeout (タイムアウト)

コレクションの要素の処理を完了するために Parallel For-Each コンポーネントのスコープ全体でかけることができる最大時間 (ミリ秒) を指定します。

たとえば、スコープ内に HTTP Request コンポーネントを配置し、GET 要求をサービスおよび Database Connector のインスタンスに送信して値をデータベースに挿入するとします。コレクションの各要素では、GET 要求で何を要求するかを指定します。​[Timeout (タイムアウト)]​ の値には、要求された情報がサービスから返され、Database Connector のインスタンスによって情報がデータベースに挿入されるまで待機する時間 (ミリ秒) を指定します。

Max Concurrency (最大同時実行)

実行可能な並列プロセスの最大数を指定します。実際に開始される並列プロセスの数は、実行されている場所でリソースが Mule Runtime によってどのように割り当てられるかに応じて異なります。

  • 値を 40 に設定し、最大 4 個のプロセスを並列実行するのに十分なリソースのみが Mule Runtime によって割り当てられた場合、最大 4 個のプロセスのみを並列実行できます。

  • 値を 2 に設定し、最大 4 個のプロセスを並列実行するのに十分なリソースが Mule Runtime によって割り当てられた場合、最大 2 個のプロセスのみを並列実行できます。

このコンポーネントを設定する場合、以下の項目に値を指定することができます (必須ではありません)。

Target (対象)

コレクションのすべての要素の処理結果を保存するために使用する変数を指定します。デフォルトでは、出力はフローのペイロードに保存されます。

Target Value (対象値)

操作の出力値に対して評価する式を指定します。この式の結果は対象変数に保存されます。デフォルトでは、これは操作の出力値と同じです。