複数のitemを一つのリストにまとめるならAggregate、item内の配列を要素ごとのitemへ分けるならSplit Outを使います。選ぶ基準は、次のノードが「複数件のitem」と「一つのitemに入った配列」のどちらを受け取るかです。
すでに3 itemsが流れているなら、各itemを処理するためだけにSplit Outを足す必要はありません。まず入力の形と欲しい出力を並べ、残すIDや親の情報を決めましょう。
AggregateとSplit Outは、itemと配列を変換する
Aggregateは流れてきたitemの情報を集め、Split Outはitem内のリストを展開するノードです。名前だけで選ぶよりも、変換前後の入れ物を見ると判断しやすくなります。
| 状態 | ノード間を流れるitem件数 | item内のorders配列長 |
|---|---|---|
| A・B・Cが別々のitem | 3 | ordersフィールドをまだ作っていない |
| Aggregateでordersに収めた後 | 1 | 3 |
| そのordersをSplit Outで展開した後 | 3 | 各itemに一つの注文を持たせる設定なら不要 |
itemの件数と、フィールド内の配列長を分けて読む
n8nのノード間データは、外側にitemの一覧があり、各itemのJSONの中に値を持つ構造です。JSONの中へ配列を入れても、それだけで外側のitemが増える仕組みではありません。
たとえばAPIから「注文が3件入ったorders配列」を受け取っても、出力が1 itemという形は自然です。その場合、次のノードで参照する$json.ordersは注文1件ではなく、注文を収めた配列になります。
一方、APIノード自身が注文を3 itemsへ展開して返す場合もあるため、APIの応答件数だけでは変換の必要性を決められません。出力パネルの件数とJSONの両方を見て、今ある形を確かめてください。
Merge・Loop Over Items・Summarizeとの違い
似た名前のノードも、扱う課題が異なります。次の表で目的を先に絞ると、不要な集約やループを足さずに済むはずです。
| 欲しい結果 | 選ぶノード | 判断のポイント |
|---|---|---|
| 複数itemを一つのリストへ収める | Aggregate | レコード全体か、個別のフィールドかを選ぶ |
| item内の配列を要素ごとのitemにする | Split Out | 対象配列と、残す親のキーを指定する |
| 別々の入力を合わせる・IDで照合する | Merge | 複数のデータ流の結合方式を決める |
| 何件ずつ処理するか、待機を挟むかを制御する | Loop Over Items | 既存itemの処理単位を決める |
| 金額の合計・平均・グループ別件数などを得る | Summarize | 一覧を作る操作と、計算を行う操作を区別する |
金額100・200・300をAggregateでまとめる基本例では、3件分の値を残す配列を作ります。合計600という結果が欲しいなら、集計演算を持つSummarizeを検討する場面です。
また、n8nは通常、複数itemを後続ノードへ渡して処理できます。ノードや操作に例外はあるものの、「3 itemsあるから必ずLoop Over Itemsが必要」とは考えないようにしましょう。
Aggregateで、残す単位を決めてまとめる
IDと金額の対応を保ちたいなら、まずAll Item Dataでレコード全体をまとめる方式が基本です。メールアドレスだけの一覧など、一つの値を集めたい場合はIndividual Fieldsが候補になります。
レコード全体を一つの配列へまとめる
ここからのデータは、説明と検証に使う仮作例です。n8n上で実測した結果ではなく、公開仕様と設定から導いた期待値として読んでください。
例Aでは、次の3 itemsを入力にします。JSON例の外側の配列がn8nのitem一覧で、各jsonの中がそのitemのデータです。
[ {"json":{"id":"A","amount":100}}, {"json":{"id":"B","amount":200}}, {"json":{"id":"C","amount":300}}]| 設定項目 | 指定値 | この指定の目的 |
|---|---|---|
| Aggregate | All Item Data | IDと金額を同じレコードのまま集める |
| Put Output in Field | orders | 後続で参照する配列名を決める |
| Include | Specified Fields | 必要な項目だけを残す |
| Fields To Include | id,amount | IDと金額の組を保持する |
| Options → Include Binaries | オフ | この例に不要なファイルを含めない |
この条件では、1 itemの中に長さ3のorders配列がある形を期待してください。A/100、B/200、C/300の組が残ることまで確認します。
[ {"json":{"orders":[ {"id":"A","amount":100}, {"id":"B","amount":200}, {"id":"C","amount":300} ]}}]後続の入力欄で配列そのものが必要なら、参照先は{{ $json.orders }}です。一つ目のレコードだけを指す{{ $json.orders[0] }}とは渡す対象が変わります。
All Item DataのIncludeでは、全フィールド、指定フィールドだけ、指定フィールド以外のいずれを含めるか選択してください。検証用のidとamount以外を不要とする今回の例では、含める項目を限定する選択です。
一つのフィールドを集める場合の注意
Individual Fieldsは、複数itemから同じフィールドの値を集める方式になります。たとえばIDだけのリストを作るなら、Input Field Nameへidを指定する用途です。
Rename Fieldを使うと出力名を変えられ、複数フィールドを集める場合はそれぞれの出力名も必要になります。idをids、amountをamountsへ集める例なら、後続がどちらを読むのかも明確です。
ただし、二つの配列を同じ位置だけで結び直す設計には注意が要ります。例Cとして、Bだけamountフィールドがない入力を考えてみましょう。
この比較では、idとamountをそれぞれids・amountsへ集め、Merge ListsとKeep Missing And Null Valuesをオフにそろえてください。欠損を省く設定の下で、idsは3要素、amountsは2要素になるのが照合用の期待値です。
| 入力ID | amountの入力 | 欠損を省く集約後の読み方 |
|---|---|---|
| A | 100 | idsはA・B・C、amountsは100・300になり得る |
| B | フィールド自体がない | 同じ位置のids[1]とamounts[1]を結ぶと、Bと300を誤対応させる |
| C | 300 | Cの金額が別のIDへ移らないよう、レコード単位で保持する |
入れ子配列・null・バイナリをどう扱うか
集めるフィールド自体が配列の場合、Individual FieldsのMerge Listsで一つの平坦なリストへまとめられます。元のitemごとのまとまりに意味があるなら、平坦化してよいかを先に決める必要がある設定です。
たとえば親ごとのタグ一覧を平坦化すると、同じタグがどの親に属していたかを配列の形だけでは読み取れなくなります。親子関係が後で必要なら、親IDと値を同じオブジェクトへ残す設計が候補です。
Keep Missing And Null Valuesを有効にすると、欠損やnullに対応するnullの要素を出力リストへ残せます。ただし、出力されたnullだけを見て「元からnullだった」「フィールドがなかった」を完全に復元できるとは限りません。
| 値・状態 | この例での扱い | 確認したいこと |
|---|---|---|
| 100、200などの数値 | 正常な金額候補 | 数値型のまま残るか |
| 0 | 有効な金額になり得る | 欠損扱いで捨てないか |
| false、空文字 | 金額欄としての適否を別途決める | 0やnullと一括して削除しないか |
| null | 値がないことを明示した状態 | 必要なら元の状態を別フィールドで記録する |
| amount自体がない | フィールド欠損 | nullと区別する必要があるか |
この表は、オプションがすべての空値をどう扱うかの実測一覧ではなく、業務入力を決めるための判断表です。対象ノードの版で0・false・空文字も別々に試し、保持する値の条件と照合してください。
画像やファイルなどのバイナリは、itemのJSONとは別に扱われます。JSONの全フィールドを含めたことだけではバイナリの保持まで確認したことにならず、必要ならInclude Binariesの設定と実際の出力を別に点検する作業です。
Split Outで、配列を要素ごとのitemへ分ける
Split Outでは、分割するフィールド、出力先の名前、親から残す項目を一組で指定します。配列を分けられても、注文と親のIDが結び付かなくなると、その後の処理で取り違える原因です。
配列のフィールド名と出力先を指定する
例Bでは、次の1 itemを入力にします。batchIdが親の識別子、ordersの中にあるidが子レコードの識別子です。
[ {"json":{ "batchId":"B01", "orders":[{"id":"A","amount":100},{"id":"B","amount":200},{"id":"C","amount":300} ] }}]| 設定項目 | 指定値 | 出力で確かめる点 |
|---|---|---|
| Field to Split Out/Fields To Split Out | orders | orders配列の要素を展開する |
| Options → Destination Field Name | order | 子の情報をorderの下へ収める |
| Include | Selected Other Fields | 必要な親の項目だけを複製する |
| Fields To Include | batchId | 全子itemに親IDを残す |
| Options → Include Binary | オフ | 親の不要なファイルを子itemへ複製しない |
分割対象の欄には、基本例ではフィールド名のordersを指定します。配列の実際の値や、配列を返す{{ $json.orders }}をそのまま入れる欄とは区別してください。
公式ドキュメントはField to Split Outという単数表記で、取得時の公式masterソースにはFields To Split Outという表記もあります。表示名に差があっても、この例では単一のorders配列だけを対象にする考え方です。
入れ子の{"payload":{"orders":[...]}}を扱うときは、ドット記法が有効ならpayload.ordersというパスで参照します。キー名そのものがpayload.ordersという文字列なら、同じ意味にはなりません。
文字としてのドットを含むキーを使う場合はDisable Dot Notationの設定と、実際に取り出したフィールドを照合してください。今回は出力先もorderという単純な名前にして、入れ子の出力先に関する版差を避ける設計です。
親IDなど、分割後も必要な項目を残す
例Bの設定で期待するのは、次の3 itemsになります。後続で子のIDを使う式は{{ $json.order.id }}、親の識別子は{{ $json.batchId }}です。
[ {"json":{"batchId":"B01","order":{"id":"A","amount":100}}}, {"json":{"batchId":"B01","order":{"id":"B","amount":200}}}, {"json":{"batchId":"B01","order":{"id":"C","amount":300}}}]親の情報を引き継ぐ範囲はIncludeで選び、No Other Fieldsは引き継がず、All Other Fieldsはほかの項目も含めます。必要な親のキーだけを指定するのが、Selected Other Fieldsです。
今回は後で親子を照合するbatchIdだけを選びます。親に連絡先や内部メモが含まれている場合、All Other Fieldsを選ぶと不要な情報まで各子itemへ広げる可能性があるためです。
親が複数ある例Dも、IDを残す理由がわかりやすいケースになります。B01にA・Bの2件、B02にCの1件があるなら、合計3子itemと、B01/A・B01/B・B02/Cという親子の組を照合する設計です。
その3 itemsを後でAggregateへ入れただけでは、B01とB02それぞれの元の形へ自動で戻るとは限りません。親別のまとまりが必要なら、親IDで分ける処理と集約の単位を別途決めてください。
空配列・型違い・複数配列は基本例と分ける
基本手順へ通す入力は、対象フィールドが配列だと確認できたものにそろえます。空配列、欠損、null、文字列やオブジェクトは、通常の3件入り配列と同一視しない方針です。
| 入力の状態 | 今回の設計上の行き先 | 理由 |
|---|---|---|
| 要素のある配列 | Split Outで展開する | 子の型と必須IDも別に確認する |
| 空配列 [] | 子なしとして記録する経路 | 処理対象の子レコードがない |
| null/フィールド欠損 | 入力要確認の経路 | 子なしと同じ理由とは限らない |
| 文字列・数値・通常オブジェクト | 入力要確認の経路 | 配列という入力条件を満たしていない |
取得時の公式masterソースには、非配列の値を包む、オブジェクトの値を展開するなどの処理が確認できます。これは導入済みのn8nと同じ実装である保証ではなく、型違いが必ずエラーで止まるとも決めつけられない理由です。
成功表示になっても、業務上ほしい子レコードが作られたとは限りません。前段で型と空の状態を分け、要確認のデータは通常の更新先へ流さないようにしましょう。
複数配列の指定に対応する実装もありますが、配列同士の長さが違う場合や出力名の条件は、対象版で確認が必要です。本例の単一配列の展開を、直積の生成やIDによる結合の代わりへ広げることはできません。
件数とIDを照合して、欠落や取り違えを見つける
完了の目安は、ノードが動いたことに加えて、必要な値と対応関係が出力に残ったことです。外部へ書き込む前に、仮作データで次の順序を確かめます。
- 本番と分けた検証用フローを用意する
既存フローを複製するなどして、送信・行更新などの外部操作を接続しない状態にします。例には架空のIDと数値を使い、実データやアクセストークンを持ち込まない構成です。
- 仮作データと期待値を用意する
例Aは3 items、例Bは配列を含む1 itemという違いを再現してください。CodeやEdit Fieldsでモックデータを作るか、開発用のピンデータを使う方法があります。
- 変換前の件数・型・IDを控える
入力item数と対象配列の長さを別々に記録し、配列内のidとamount、親のbatchIdも照合の基準として控えましょう。
- 変換するノードだけを設定・実行する
例AはAggregate、例BはSplit Outの設定表へ合わせてください。JSON項目の選択に加え、不要なバイナリを持ち出していないかも見る手順です。
- 同じ実行の入力と出力を照合する
出力件数、IDと値の組、親子キー、余分な項目を見ます。過去の出力や別のピンデータを混ぜると、設定変更が反映したかを判定できません。
- 欠損・空・型違いを一件ずつ試す
例Cのamount欠損、空配列、null、フィールド欠損などを別ケースに分けてください。異常なデータの行き先まで合っていることが、後続へ接続する条件です。
- 期待外なら接続を止め、設定を一つずつ戻す
キー欠落や予定外の件数増加があれば、外部更新へ進めません。隔離したフローを停止し、複製元との差分を見ながら変換設定を戻して、同じ入力で再確認します。
ピンデータは開発用の機能で、本番実行へ同じ固定入力を適用する仕組みではありません。すでに外部へ送信・更新した内容は、変換設定を戻すだけで取り消せるものでもないため、テスト段階で後続を切り離す判断が大切です。
3→1→3だけでは、元に戻ったとは限らない
件数が同じでも、IDと値の対応が違えば復元できていません。例Aと例Bは期待する入出力の形を示す別のテストで、あらゆる設定の完全な逆変換を保証する例ではない点も押さえてください。
- 例A:1 itemのordersに3要素があり、A/100・B/200・C/300が同じレコードに残っている
- 例B:3 itemsの各batchIdがB01で、order.idとorder.amountが元の組と一致している
- 例C:Bのamount欠損が、Cの300をBへ割り当てる結果になっていない
- 例D:3子itemだけでなく、B01/A・B01/B・B02/Cという親子キーが保たれている
- 必要な項目の型が維持され、不要な個人情報やバイナリが追加されていない
集約後に過去ノードの$("ノード名").itemを参照すると、対応候補が複数になり、一意に選べない場合があります。集約済みのordersを扱う処理なら、まず現在の出力データ自身を参照する方針です。
公式には.first()などで位置を指定する方法もありますが、それが正しいレコードを選ぶかは処理の目的で変わります。エラーを消すためだけに先頭へ固定せず、必要なIDのデータを取得しているかまで照合しましょう。
結果が少ない・一つしか動かないときの確認順
設定を同時にいくつも変えると、どこで欠落したかがわからなくなります。同じ仮作入力を使い、次の順序で原因を絞る方法です。
| 順序 | 見る場所 | 結果に応じた次の行動 |
|---|---|---|
| 1 | 今回実行の入力・ピンの有無 | 入力が違えば、テストデータをそろえて再実行する |
| 2 | 対象フィールド名・入れ子のパス・配列型 | ordersが存在し、意図した配列を指すか確認する |
| 3 | Aggregateの含める項目・欠損保持、Split OutのInclude | 消えたキーと設定を対応させ、必要な項目だけを戻す |
| 4 | SettingsのExecute Once | オンなら先頭itemだけを使う設定。複数入力を処理する要件との一致を見る |
| 5 | SettingsのAlways Output Data | 空の結果へ空itemが補われていないか確認する |
| 6 | 後続が期待する形と参照式 | orders配列かorderオブジェクトかを合わせ、IDで照合する |
Always Output Dataは、空だった結果を注文1件へ直す設定ではありません。空itemまで通常レコードとして数える集計は、件数だけ合っても必要なIDを持たない出力を見逃す原因です。
Execute OnceやAlways Output Dataを切り替えると、入力の扱いや空の結果が変わります。症状を消す万能な修正として使わず、前後の出力と設定変更の理由を記録する作業です。
次の処理に合わせて、結合・反復へ進む
変換結果が期待どおりなら、次に必要な処理を決めます。配列とitemの形を整えた段階で、別入力との照合や外部更新まで完了したわけではありません。
- 別々に取得した注文と顧客をIDで合わせるなら、Mergeで照合キーと未一致の扱いを決める
- 一度に処理する件数や待機を制御するなら、通常のitem処理で足りるかを見てからLoop Over Itemsを検討する
- 型違いや空配列を別ルートへ送るなら、IF・Switch・Filterで条件と未一致の行き先を設計する
- Google Sheetsへ書くなら、認証・対象シート・更新する行の識別と、書き込み後の読み戻しを別に確認する
たとえばSplit Outで3子itemになった後に行更新ノードをつなぐなら、更新対象を注文IDで特定できることが次の条件です。親IDが同じ3件を重複と決めつけて削ると、別の明細まで失うおそれがあります。
ここまでの件数や参照先を確認してもノードが失敗する場合は、表示されたエラーと失敗したノードを控え、APIやネットワークを含む原因の切り分けへ進めてください。変換前後のJSONと対象版が残っていれば、構造の問題か別の障害かを分ける材料になります。
まとめ|AggregateとSplit Outは、件数とIDを確かめて使う
複数itemをリストへまとめるのがAggregate、item内の配列を要素ごとのitemへ展開するのがSplit Outです。使う前に欲しい出力を決め、IDと値の組や親IDを残す設定を選びます。
まずは架空のA・B・Cの3件で、例Aの集約と例Bの展開をそれぞれ試してください。件数だけでなく、A/100などの対応、親子キー、空や欠損の行き先まで合うことが、後続の更新処理へ進む条件です。
ノードを追加する前に入力と必要な出力を並べる方法は、誤った変換を見つけやすくします。特にIDを持った小さな例から始めると、単なる「成功表示」よりも、何が保たれ何が失われるかを判断しやすい設計です。