All Products
Search
Document Center

DataWorks:for-each node

Last Updated:Aug 14, 2026

Node for-each melakukan iterasi terhadap result set hulu, seperti daftar nama file atau partisi, lalu mengeksekusi subtask yang sama untuk setiap elemen. Hal ini menghilangkan kebutuhan membuat tugas individual secara manual dan memungkinkan alur kerja yang dinamis serta otomatis.

Use cases

for-each node memungkinkan eksekusi berparameter saat Anda perlu menerapkan logika analisis atau pemrosesan yang sama pada unit bisnis, lini produk, atau item konfigurasi yang berbeda. Misalnya, jika perusahaan Anda memiliki beberapa lini produk dan Anda perlu menghasilkan laporan harian terpisah untuk masing-masing, logika pemrosesannya identik; hanya data target yang berbeda.

Seperti halnya loop for dalam bahasa pemrograman, for-each node melakukan iterasi terhadap daftar—seperti nama tabel, nama partisi, atau nama file—lalu mengeksekusi sub-alur kerja yang telah ditentukan untuk setiap item.

Usage notes

  • Version requirements: Hanya tersedia di DataWorks Edisi Standar dan versi yang lebih baru.

  • Permissions: Akun RAM Anda harus ditambahkan ke workspace target dan diberi peran developer atau workspace administrator. Untuk informasi selengkapnya, lihat Add members to a workspace.

How it works

Node for-each bertindak sebagai wadah yang membungkus sub-alur kerja yang dapat dikustomisasi, yang dikenal sebagai loop body. Cara kerjanya sebagai berikut:

  1. Data input: Node for-each bergantung pada assignment node hulu atau node lain yang dapat ditetapkan (seperti EMR Hive node). Node ini mengambil result set berformat array dengan mengikat parameter loopDataArray.

  2. Loop execution: Saat node dimulai, node tersebut melakukan iterasi terhadap setiap elemen dalam result set secara berurutan. Untuk setiap elemen, node tersebut mengeksekusi sepenuhnya loop body internal satu kali, dari node Start hingga node End.

    Catatan

    Node Start dan End tidak dapat diedit. Keduanya hanya menandai awal dan akhir loop body.

  3. Data passing: Selama setiap iterasi, nilai elemen saat ini diteruskan ke node di dalam loop body melalui built-in variables. Node bisnis internal menggunakan ${dag.foreach.current} untuk mengakses item data yang sedang diproses.

Built-in parameters

Penting

Variabel dalam format ${...} merupakan sintaks templat khusus DataWorks. DataWorks langsung mengurai parameter ini dan menggantinya dengan nilainya sebelum eksekusi.

Node dalam loop body for-each dapat menggunakan built-in variables berikut untuk mengakses status dan data loop:

Built-in parameter

Description

For loop analogy

${dag.loopDataArray}

Result set lengkap yang diteruskan dari assignment node hulu.

Pertimbangkan kode loop for berikut:

for(int i=0;i<data.length;i++) {
   print(data[i]);
}
  • ${dag.loopDataArray} berkorespondensi dengan data.

  • ${dag.foreach.current} berkorespondensi dengan data[i].

  • ${dag.offset} berkorespondensi dengan i.

  • ${dag.loopTimes} berkorespondensi dengan i+1.

${dag.foreach.current}

Item data yang sedang diproses pada iterasi saat ini.

${dag.offset}

Offset loop saat ini (diindeks mulai dari 0).

${dag.loopTimes}

Hitungan putaran saat ini (indeks dimulai dari 1).

Jika output hulu berupa array dua dimensi, seperti hasil kueri SQL, Anda juga dapat menggunakan sintaks berikut untuk mengakses nilai tertentu:

Other parameters

Description

${dag.foreach.current}

Mendapatkan string dengan memisahkan elemen baris data saat ini (array satu dimensi) menggunakan koma ,.

${dag.foreach.current[n]}

Item ke-n dari baris data saat ini.

${dag.loopDataArray[i][j]}

Data dari baris ke-i dan kolom ke-j dari seluruh result set.

for-each node saat ini tidak mendukung nested loops. Contoh ini hanya untuk demonstrasi pengambilan nilai.

Limitations

  • Execution mechanism: Loop mendukung serial execution maupun parallel execution. Anda dapat memilih eksekusi parallel ketika iterasi bersifat independen satu sama lain.

  • Loop limit: Jumlah maksimum loop default adalah 128, yang dapat disesuaikan hingga 1024.

  • Debugging constraints: Anda tidak dapat menjalankan node for-each secara langsung di Data Studio. Anda harus deploy tugas tersebut lalu mengujinya di Operation Center menggunakan fitur smoke testing.

  • Execution constraints: Node for-each tidak dapat dijalankan secara terisolasi. Ini mencakup smoke testing, backfill, dan eksekusi manual.

  • Flow control in the loop body: Jika Anda menggunakan branch node di dalam loop body for-each, pastikan semua cabang akhirnya menyatu pada satu merge node sebelum terhubung ke node End. Hal ini menjamin integritas logis loop body.

  • Rerun constraints: Setelah node di-deploy, automatic rerun on failure dilanjutkan dari titik kegagalan. Namun, rerun manual memicu rerun lengkap seluruh node for-each.

Procedure

Prosedur ini menggunakan assignment node sebagai node hulu dan node Shell di dalam loop body untuk mencetak hasilnya. Prosedur ini menjelaskan langkah-langkah konfigurasi tugas for-each secara lengkap:

  1. Siapkan data hulu (konfigurasikan assignment node)

    Buat dan konfigurasikan assignment node untuk menyediakan result set yang dapat diiterasi bagi node for-each hulu.

    1. Di alur kerja, buat assignment node (misalnya, assign) dan letakkan di hulu node for-each.

    2. Klik ganda assignment node dan pilih lingkungan Python 2. Misalnya, gunakan Python 2 untuk menghasilkan array dengan empat elemen:

      Node mengeluarkan [10,20,30,40] ke node-node hilir dengan secara otomatis memisahkan baris output terakhir menjadi array berdasarkan setiap koma.
      print "10,20,30,40"
    3. Assignment node secara otomatis menghasilkan parameter output bernama outputs, yang merepresentasikan result set-nya.

    4. Save assignment node.

  2. Konfigurasikan for-each node untuk mengonsumsi data

    Konfigurasikan node for-each agar menerima data hulu dan menggunakannya di dalam loop body-nya.

    1. Klik ganda node for-each untuk membuka canvas internalnya.

    2. Di panel Scheduling di sebelah kanan, temukan parameter loopDataArray di bawah Scheduling Parameters lalu klik Bind.

      Pilih parameter outputs dari node assign untuk membuat binding. Setelah binding selesai, nilai parameter loopDataArray mencerminkan status binding-nya.

    3. Di kotak dialog yang muncul, atur Value Source ke assignment node hulu (assign) dan pilih parameter outputs-nya. Tindakan ini secara otomatis membuat dependensi antara kedua node.

    4. Di loop body for-each, klik Create Internal Node dan buat node Shell.

      Dalam skenario dunia nyata, Anda dapat mengonfigurasi jenis node apa pun.
    5. Klik ganda node Shell baru dan gunakan built-in variables dalam kode untuk mengambil dan mencetak informasi tentang loop:

      #!/bin/bash
      # Gunakan ${dag.loopTimes} untuk mendapatkan jumlah loop saat ini
      echo "Current loop number is: ${dag.loopTimes}"
      # Gunakan ${dag.foreach.current} untuk mendapatkan item data untuk iterasi saat ini
      echo "Current item is: ${dag.foreach.current}"
    6. (Opsional) Di panel Scheduling Settings di sebelah kanan, konfigurasikan properti di bawah Scheduling Policy.

      • Maximum Number of Loops: Default-nya adalah 128, dan maksimumnya adalah 1024.

        Penting

        Parameter ini menentukan jumlah maksimum iterasi untuk loop body. Jika jumlah item data hulu besar, tingkatkan nilai ini untuk memastikan semua item diproses.

      • Execute Policy: Pilih Serial untuk contoh ini.

        • Serial: Menjalankan iterasi secara berurutan.

        • Parallel: Menjalankan iterasi loop secara konkuren untuk meningkatkan efisiensi tugas. Dalam mode Parallel, jika satu iterasi gagal, iterasi lain tidak terpengaruh. Penjadwal berusaha menjalankan semua iterasi hingga selesai. Konkurensi default-nya adalah 5, dan maksimumnya adalah 20.

    7. Save node Shell.

  3. Deploy, jalankan, dan verifikasi

    Deploy alur kerja ke Operation Center untuk dieksekusi dan verifikasi hasil node for-each.

    1. Kembali ke canvas alur kerja utama dan klik tombol Deploy di toolbar untuk memublikasikan seluruh alur kerja.

    2. Buka Node O&M > Auto Triggered Task O&M > Auto Triggered Task dan lakukan smoke test pada alur kerja target.

      Penting

      Jangan lakukan smoke test pada node for-each secara individual. Karena node for-each bergantung pada output assignment node hulu, Anda harus memulai pengujian dari assignment node untuk memastikan alur data lengkap.

    3. Setelah test instance berhasil dijalankan, temukan instans node for-each di daftar, buka, lalu klik kanan dan pilih View Internal Nodes.

    4. Di tampilan node internal, periksa instans node Shell yang dihasilkan oleh setiap loop. Buka running log salah satu instans untuk melihat output iterasi tersebut dan verifikasi bahwa output-nya benar.

      Panel kiri menunjukkan bahwa keempat iterasi loop telah selesai. Running log untuk iterasi keempat mengeluarkan Current loop number is: 4 dan Current item is: 40, serta perintah Shell keluar dengan kode 0, yang menunjukkan eksekusi berhasil.

Catatan

Selain menggunakan assignment node tradisional sebagai node hulu, node for-each juga mendukung pencapaian efek iterasi yang sama melalui fitur assignment parameter dari node SQL hulu. Untuk jenis node yang mendukung assignment parameter, seperti EMR Hive, Hologres SQL, EMR Spark SQL, AnalyticDB for PostgreSQL, ClickHouse SQL, dan MySQL, Anda dapat menambahkan assignment parameter di bagian Node Context Parameters > Output Parameters of This Node.

Use case: Process different data formats

Scenario 1: Process a one-dimensional array

  • assignment node output: 2025-11-01,2025-11-02,2025-11-03

  • Iteration count: 3

  • During the second iteration:

    • Nilai ${dag.foreach.current} adalah 2025-11-02.

    • Nilai ${dag.loopTimes} adalah 2.

Scenario 2: Process a two-dimensional array

  • assignment node (MaxCompute SQL) output:

    +-----+----------+
    | id  | city     |
    +-----+----------+
    | 101 | beijing  |
    | 102 | shanghai |
    +-----+----------+
  • Iteration count: 2

  • During the second iteration:

    • Nilai ${dag.foreach.current} adalah 102,shanghai.

    • Nilai ${dag.loopTimes} adalah 2.

    • Nilai ${dag.foreach.current[0]} adalah 102.

    • Nilai ${dag.foreach.current[1]} adalah shanghai.

Scenario: Batch process partition table data across multiple business lines

Contoh ini menunjukkan cara menggunakan assignment node dan for-each node untuk memproses data perilaku pengguna secara batch di berbagai lini bisnis, mengotomatiskan pemrosesan data dengan satu set logika yang melayani beberapa lini produk.

image

Background

Asumsikan Anda adalah insinyur pengembangan data di perusahaan internet komprehensif, bertanggung jawab untuk memproses data dari tiga lini bisnis inti: e-dagang (ecom), keuangan (finance), dan logistik (logistics), dengan kemungkinan penambahan lebih banyak di masa depan. Anda perlu menjalankan logika agregasi yang sama pada log perilaku pengguna dari ketiga lini bisnis ini setiap hari untuk menghitung daily page views (PV) per pengguna dan menyimpan hasilnya di tabel agregat terpadu.

  • Tabel sumber hulu (lapisan DWD):

    • dwd_user_behavior_ecom_d: Tabel perilaku pengguna e-dagang.

    • dwd_user_behavior_finance_d: Tabel perilaku pengguna keuangan.

    • dwd_user_behavior_logistics_d: Tabel perilaku pengguna logistik.

    • dwd_user_behavior_${business_line}_d: Tabel perilaku pengguna untuk lini bisnis potensial lainnya di masa depan.

    • Tabel-tabel ini memiliki skema yang sama dan dipartisi berdasarkan hari (dt).

  • Tabel target hilir (lapisan DWS):

    • dws_user_summary_d: Tabel agregat pengguna.

    • Tabel ini dipartisi ganda berdasarkan lini bisnis (biz_line) dan hari (dt) untuk menyimpan hasil agregasi dari semua lini bisnis secara terpadu.

Membuat tugas terpisah untuk setiap lini bisnis mengakibatkan biaya maintenance tinggi dan rentan kesalahan. Dengan node for-each, Anda mempertahankan satu set logika pemrosesan, dan sistem secara otomatis melakukan iterasi melalui semua lini bisnis untuk menyelesaikan komputasi.

Data preparation

Pertama, buat tabel sampel dan masukkan data uji (menggunakan tanggal bisnis 20251010 sebagai contoh).

  1. Associate a compute resource dengan workspace.

  2. Buka Data Studio untuk pengembangan data dan buat node MaxCompute SQL.

  3. Buat tabel sumber (lapisan DWD): Tambahkan kode berikut ke node MaxCompute SQL dan jalankan.

    -- Tabel perilaku pengguna e-dagang
    CREATE TABLE IF NOT EXISTS dwd_user_behavior_ecom_d (
        user_id     STRING COMMENT 'User ID',
        action_type STRING COMMENT 'Action type',
        event_time  BIGINT COMMENT 'Event timestamp in milliseconds (Unix)'
    ) 
    COMMENT 'E-commerce user behavior log detail table'
    PARTITIONED BY (dt STRING COMMENT 'Date partition, format yyyymmdd');
    INSERT OVERWRITE TABLE dwd_user_behavior_ecom_d PARTITION (dt='20251010') VALUES
    ('user001', 'click',        1760004060000), -- 2025-10-10 10:01:00.000
    ('user002', 'browse',       1760004150000), -- 2025-10-10 10:02:30.000
    ('user001', 'add_to_cart',  1760004300000); -- 2025-10-10 10:05:00.000
    -- Verifikasi tabel perilaku pengguna e-dagang berhasil dibuat
    SELECT * FROM dwd_user_behavior_ecom_d where dt='20251010';
    -- Tabel perilaku pengguna keuangan
    CREATE TABLE IF NOT EXISTS dwd_user_behavior_finance_d (
        user_id     STRING COMMENT 'User ID',
        action_type STRING COMMENT 'Action type',
        event_time  BIGINT COMMENT 'Event timestamp in milliseconds (Unix)'
    ) 
    COMMENT 'Finance user behavior log detail table'
    PARTITIONED BY (dt STRING COMMENT 'Date partition, format yyyymmdd');
    INSERT OVERWRITE TABLE dwd_user_behavior_finance_d PARTITION (dt='20251010') VALUES
    ('user003', 'open_app',      1760020200000), -- 2025-10-10 14:30:00.000
    ('user003', 'transfer',      1760020215000), -- 2025-10-10 14:30:15.000
    ('user003', 'check_balance', 1760020245000), -- 2025-10-10 14:30:45.000
    ('user004', 'open_app',      1760020300000); -- 2025-10-10 14:31:40.000
    -- Verifikasi tabel perilaku pengguna keuangan berhasil dibuat
    SELECT * FROM dwd_user_behavior_finance_d where dt='20251010';
    -- Tabel perilaku pengguna logistik
    CREATE TABLE IF NOT EXISTS dwd_user_behavior_logistics_d (
        user_id     STRING COMMENT 'User ID',
        action_type STRING COMMENT 'Action type',
        event_time  BIGINT COMMENT 'Event timestamp in milliseconds (Unix)'
    ) 
    COMMENT 'Logistics user behavior log detail table'
    PARTITIONED BY (dt STRING COMMENT 'Date partition, format yyyymmdd');
    INSERT OVERWRITE TABLE dwd_user_behavior_logistics_d PARTITION (dt='20251010') VALUES
    ('user001', 'check_status',    1760032800000), -- 2025-10-10 18:00:00.000
    ('user005', 'schedule_pickup', 1760032920000); -- 2025-10-10 18:02:00.000
    -- Verifikasi tabel perilaku pengguna logistik berhasil dibuat
    SELECT * FROM dwd_user_behavior_logistics_d where dt='20251010';
  4. Buat tabel target (lapisan DWS): Tambahkan kode berikut ke node MaxCompute SQL dan jalankan.

    CREATE TABLE IF NOT EXISTS dws_user_summary_d (
        user_id     STRING COMMENT 'User ID',
        pv          BIGINT COMMENT 'Daily activity count'
    ) 
    COMMENT 'User daily activity summary table'
    PARTITIONED BY (
        dt           STRING COMMENT 'Date partition, format yyyymmdd',
        biz_line     STRING COMMENT 'Business line partition, e.g. ecom, finance, logistics'
    );
    Penting

    Jika workspace menggunakan mode standar, Anda perlu deploy node ini ke lingkungan produksi dan backfill data.

Workflow implementation

  1. Buat alur kerja. Di bagian Scheduling Parameters di sisi kanan, atur parameter penjadwalan bizdate ke hari sebelumnya: $[yyyymmdd-1].

  2. Di alur kerja, buat assignment node bernama get_biz_list dan tulis kode berikut dalam MaxCompute SQL. Node ini mengeluarkan daftar lini bisnis yang akan diproses:

    -- Output semua lini bisnis yang akan diproses
    SELECT 'ecom' AS biz_line
    UNION ALL
    SELECT 'finance' AS biz_line
    UNION ALL
    SELECT 'logistics' AS biz_line;
  3. Konfigurasikan node for-each

    • Kembali ke halaman alur kerja dan buat node for-each hilir untuk assignment node get_biz_list.

    • Buka halaman pengaturan for-each node. Di bagian Scheduling Parameters > Script Parameters di bawah schedule settings di sisi kanan, ikat parameter loopDataArray ke outputs dari node get_biz_list.

    • Di loop body node for-each, klik Create Internal Node dan buat node MaxCompute SQL. Tulis logika pemrosesan di dalam loop body.

      Catatan
      • Skrip ini digerakkan oleh node for-each dan dieksekusi sekali untuk setiap lini bisnis.

      • Variabel built-in ${dag.foreach.current} secara dinamis diganti dengan nama lini bisnis saat ini pada setiap iterasi. Nilai iterasi yang diharapkan adalah: 'ecom', 'finance', 'logistics'.

      SET odps.sql.allow.dynamic.partition=true;
      INSERT OVERWRITE TABLE dws_user_summary_d PARTITION (dt='${bizdate}', biz_line)
      SELECT
          user_id,
          COUNT(*) AS pv,
          '${dag.foreach.current}' AS biz_line
      FROM
          dwd_user_behavior_${dag.foreach.current}_d
      WHERE
          dt = '${bizdate}'
      GROUP BY
          user_id;
  4. Tambahkan node verifikasi

    Kembali ke alur kerja. Klik Create Downstream pada node for-each untuk membuat MaxCompute SQL node dan tambahkan kode berikut.

    SELECT * FROM dws_user_summary_d WHERE dt='20251010' ORDER BY biz_line, user_id;

Deployment and results

Deploy alur kerja ke lingkungan produksi. Buka halaman Auto Triggered Task O&M > Auto Triggered Task di Operation Center. Temukan alur kerja target dan lakukan smoke testing dengan tanggal bisnis diatur ke '20251010'.

Setelah eksekusi selesai, lihat log waktu proses di test instance. Output yang diharapkan dari node terakhir adalah sebagai berikut:

user_id

pv

dt

biz_line

user001

2

20251010

ecom

user002

1

20251010

ecom

user003

3

20251010

finance

user004

1

20251010

finance

user001

1

20251010

logistics

user005

1

20251010

logistics

Advantages

  • High scalability: Untuk menambahkan lini bisnis baru, cukup tambahkan satu baris SQL di assignment node tanpa mengubah logika pemrosesan.

  • Easy maintenance: Semua lini bisnis berbagi satu set logika pemrosesan. Satu modifikasi berlaku untuk semuanya.

FAQ

  • Q: Mengapa saya tidak bisa menjalankan node for-each secara langsung di Data Studio untuk mengujinya?

    A: Ini sesuai desain. Node tersebut memerlukan lingkungan penjadwalan lengkap untuk menyelesaikan node context dan dependensinya, sehingga tidak mendukung eksekusi langsung di Data Studio. Anda harus deploy tugas tersebut ke Operation Center dan mengujinya menggunakan backfill atau memicu eksekusi terjadwal.

  • Q: Mengapa smoke test pada node for-each individual gagal atau tidak melakukan apa-apa?

    A: Data loop untuk node for-each berasal dari parameter input loopDataArray, yang harus bound ke parameter outputs dari assignment node hulu. Jika Anda menjalankan node for-each sendirian, node tersebut akan gagal atau dilewati karena tidak dapat menerima result set input.

  • Q: Mengapa loop saya hanya berjalan sekali? 

    A: Hal ini biasanya terjadi karena output dari assignment node hulu diurai sebagai satu elemen tunggal. Periksa output Anda:

    • 1. Apakah berupa string tunggal tanpa pembatas?

    • 2. Jika Anda ingin melakukan iterasi pada beberapa item, pastikan item-item tersebut dipisahkan dengan koma (,). Misalnya, 'item1,item2,item3' menghasilkan tiga loop, sedangkan 'item1 item2 item3' hanya menghasilkan satu loop.