All Products
Search
Document Center

DataWorks:for-each node

Last Updated:Jun 22, 2026

Dalam alur kerja pemrosesan data, Anda dapat menggunakan for-each node untuk mengeksekusi subtask yang sama terhadap setiap item dalam daftar, seperti daftar nama file atau partisi. Node ini secara otomatis melakukan iterasi terhadap set hasil dari node hulu—biasanya assignment node—dan menjalankan isi loop-nya sekali untuk setiap elemen. Pendekatan ini mengotomatiskan dan menyederhanakan alur kerja dengan menghilangkan kebutuhan membuat tugas individual secara manual.

Kasus penggunaan

Dalam pengembangan data sehari-hari, for-each node memungkinkan eksekusi berparameter ketika Anda perlu menerapkan logika analisis atau pemrosesan yang sama pada berbagai unit bisnis, lini produk, atau item konfigurasi. 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 loop for dalam bahasa pemrograman, for-each node secara otomatis melakukan iterasi terhadap daftar, seperti nama tabel, nama partisi, atau nama file. Node ini mengeksekusi sub-alur kerja yang telah ditentukan untuk setiap item dalam daftar, sehingga meningkatkan otomatisasi dan fleksibilitas alur kerja secara signifikan.

Prasyarat

  • Persyaratan edisi: Fitur ini hanya tersedia di DataWorks Edisi Standar dan versi yang lebih baru.

  • Persyaratan izin: Akun RAM Anda harus ditambahkan ke ruang kerja yang sesuai dan diberikan peran Development atau Workspace Manager. Untuk informasi selengkapnya, lihat Add members to a workspace.

Cara kerja

For-each node bertindak sebagai kontainer yang membungkus sub-alur kerja yang dapat dikustomisasi, yang dikenal sebagai isi loop. Mekanismenya adalah sebagai berikut:

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

  2. Eksekusi loop: Saat node dimulai, node tersebut melakukan iterasi terhadap setiap elemen dalam result set secara berurutan. Untuk setiap elemen, node tersebut mengeksekusi sepenuhnya isi loop sekali, dari node Start hingga node End.

    Catatan

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

  3. Penyaluran data: Selama setiap iterasi, nilai elemen saat ini diteruskan ke node di dalam isi loop melalui variabel bawaan. Node bisnis internal menggunakan ${dag.foreach.current} untuk mengakses item data yang sedang diproses.

Parameter bawaan

Penting

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

Node di dalam isi loop for-each dapat menggunakan variabel bawaan berikut untuk mengakses status dan data loop:

Parameter bawaan

Deskripsi

Analogi loop

${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} bersesuaian dengan data.

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

  • ${dag.offset} bersesuaian dengan i.

  • ${dag.loopTimes} bersesuaian 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 perulangan saat ini (berbasis 1).

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

Parameter lainnya

Deskripsi

${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 loop bersarang. Contoh ini hanya untuk demonstrasi pengambilan nilai.

Batasan

  • Mekanisme eksekusi: Loop mendukung eksekusi serial dan eksekusi paralel. Anda dapat memilih eksekusi paralel ketika iterasi saling independen.

  • Batas loop: Jumlah maksimum loop default adalah 128, yang dapat disesuaikan hingga 1.024.

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

  • Batasan eksekusi: For-each node tidak dapat dijalankan secara terisolasi. Ini mencakup smoke testing, backfill, dan eksekusi manual.

  • Kontrol alur dalam isi loop: Jika Anda menggunakan branch node di dalam isi loop for-each, pastikan semua cabang akhirnya bertemu pada satu merge node sebelum terhubung ke node End. Hal ini menjamin integritas logis isi loop.

  • Batasan eksekusi ulang: Setelah node di-deploy, eksekusi ulang otomatis saat gagal dilanjutkan dari titik kegagalan. Namun, eksekusi ulang manual memicu eksekusi ulang lengkap seluruh for-each node.

Prosedur

Prosedur ini menggunakan assignment node sebagai node hulu dan node Shell di dalam isi loop untuk mencetak hasilnya. Bagian ini memandu Anda melalui konfigurasi tugas for-each yang lengkap:

  1. Siapkan data hulu (konfigurasikan assignment node)

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

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

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

      Node ini menghasilkan [10,20,30,40] ke node hilir dengan secara otomatis memisahkan baris output terakhir menjadi array pada 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 for-each node agar menerima data hulu dan menggunakannya di dalam isi loop-nya.

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

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

      Pilih parameter outputs dari node assign untuk membuat ikatan. Setelah ikatan selesai, nilai parameter loopDataArray mencerminkan status terikatnya.

    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 isi loop 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 variabel bawaan 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 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 1.024.

        Penting

        Parameter ini menentukan jumlah maksimum iterasi untuk isi loop. 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 Paralel, 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. Simpan node Shell.

  3. Deploy, Run, and Verify

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

    1. Kembali ke canvas alur kerja utama dan klik tombol Deploy di bilah alat 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 for-each node secara individual. Karena for-each node bergantung pada output assignment node hulu, Anda harus memulai pengujian dari assignment node untuk memastikan alur data lengkap.

    3. Setelah instans uji berhasil dijalankan, temukan instans for-each node 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 menghasilkan Current loop number is: 4 dan Current item is: 40, serta perintah Shell keluar dengan kode 0, yang menunjukkan eksekusi berhasil.

Kasus penggunaan: Memproses berbagai format data

Skenario 1: Memproses array satu dimensi

  • keluaran node penugasan: 2025-11-01, 2025-11-02, 2025-11-03

  • Jumlah iterasi: 3

  • Selama iterasi kedua:

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

    • Nilai ${dag.loopTimes} adalah 2.

Skenario 2: Memproses array dua dimensi

  • Output assignment node (MaxCompute SQL):

    +-----+----------+
    | id  | city     |
    +-----+----------+
    | 101 | beijing  |
    | 102 | shanghai |
    +-----+----------+
  • Jumlah iterasi: 2

  • Selama iterasi kedua:

    • 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.

Kasus penggunaan: Pemrosesan batch untuk beberapa lini bisnis

Contoh ini menunjukkan cara menggunakan assignment node dan for-each node untuk memproses data perilaku pengguna secara batch untuk beberapa lini bisnis. Hal ini memungkinkan pemrosesan data otomatis di mana satu set logika melayani beberapa lini produk.

Latar belakang

Asumsikan Anda adalah insinyur data di perusahaan besar yang bertanggung jawab memproses data dari tiga lini bisnis inti: e-dagang (ecom), keuangan (finance), dan logistik (logistics), dengan kemungkinan penambahan lini lain di masa depan. Anda perlu menerapkan logika agregasi yang sama pada log perilaku pengguna dari lini bisnis ini setiap hari untuk menghitung page views harian (PV) untuk setiap pengguna dan menyimpan hasilnya dalam tabel ringkasan 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_${line_of_business}_d : Tabel perilaku pengguna untuk lini bisnis potensial lainnya.

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

  • Tabel tujuan hilir (lapisan DWS):

    • dws_user_summary_d : Tabel ringkasan pengguna.

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

Dengan menggunakan for-each node, Anda hanya perlu memelihara satu set logika pemrosesan, dan sistem secara otomatis melakukan iterasi melalui semua lini bisnis untuk menyelesaikan perhitungan.

Persiapan data

Pertama, buat tabel contoh dan masukkan data uji. Contoh ini menggunakan tanggal bisnis 20251010.

  1. Asosiasikan resource komputasi MaxCompute dengan ruang kerja.

  2. Buka Data Studio dan buat node MaxCompute SQL.

  3. Buat tabel sumber (lapisan DWD). Di node MaxCompute SQL, tambahkan kode berikut, pilih, lalu 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 'Behavior type',
        event_time  BIGINT COMMENT 'Event time as a millisecond-level Unix timestamp'
    ) 
    COMMENT 'E-commerce user behavior log detail table'
    PARTITIONED BY (dt STRING COMMENT 'Date partition in yyyymmdd format');
    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 bahwa tabel perilaku pengguna e-dagang telah 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 'Behavior type',
        event_time  BIGINT COMMENT 'Event time as a millisecond-level Unix timestamp'
    ) 
    COMMENT 'Finance user behavior log detail table'
    PARTITIONED BY (dt STRING COMMENT 'Date partition in yyyymmdd format');
    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 bahwa tabel perilaku pengguna keuangan telah 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 'Behavior type',
        event_time  BIGINT COMMENT 'Event time as a millisecond-level Unix timestamp'
    ) 
    COMMENT 'Logistics user behavior log detail table'
    PARTITIONED BY (dt STRING COMMENT 'Date partition in yyyymmdd format');
    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 bahwa tabel perilaku pengguna logistik telah dibuat.
    SELECT * FROM dwd_user_behavior_logistics_d where dt='20251010';
  4. Buat tabel tujuan (lapisan DWS). Di node MaxCompute SQL, tambahkan kode berikut, pilih, lalu jalankan.

    CREATE TABLE IF NOT EXISTS dws_user_summary_d (
        user_id     STRING COMMENT 'User ID',
        pv          BIGINT COMMENT 'Daily page views'
    ) 
    COMMENT 'User daily page views summary table'
    PARTITIONED BY (
        dt           STRING COMMENT 'Date partition in yyyymmdd format',
        biz_line     STRING COMMENT 'Line of business partition, such as ecom, finance, or logistics'
    );
    Penting

    Jika ruang kerja Anda menggunakan lingkungan pengembangan standar, Anda harus deploy node ini ke lingkungan produksi dan melakukan data backfill.

Implementasi alur kerja

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

  2. Di alur kerja, buat assignment node bernama get_biz_list. Gunakan bahasa MaxCompute SQL untuk menulis kode berikut. Node ini menghasilkan 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 for-each node

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

    • Buka panel pengaturan for-each node. Di panel Scheduling di sebelah kanan, di bawah tab Scheduling Parameters > Script Parameters, ikat parameter loopDataArray ke outputs node get_biz_list.

    • Di isi loop for-each node, klik Create Internal Node untuk membuat node MaxCompute SQL, lalu tulis logika pemrosesan untuk isi loop.

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

      • Saat runtime, sistem secara dinamis mengganti variabel bawaan ${dag.foreach.current} dengan nama lini bisnis saat ini. Nilai iterasi yang diharapkan adalah 'ecom', 'finance', dan '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 canvas alur kerja. Untuk for-each node, klik Create Downstream untuk membuat node MaxCompute SQL, lalu tambahkan kode berikut.

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

Deployment dan hasil

Deploy alur kerja ke lingkungan produksi. Buka Auto Triggered Task O&M > Auto Triggered Task O&M > Auto Triggered Task, temukan alur kerja, lalu jalankan smoke test. Pilih '20251010' sebagai tanggal bisnis.

Setelah eksekusi selesai, node terakhir menghasilkan output 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

Manfaat

  • Skalabilitas tinggi: Untuk menambahkan lini bisnis baru, Anda hanya perlu menambahkan satu baris SQL ke assignment node tanpa mengubah logika pemrosesan.

  • Pemeliharaan mudah: Semua lini bisnis berbagi logika pemrosesan yang sama. Perubahan di satu tempat berlaku untuk semuanya.

FAQ

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

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

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

    A: Data loop untuk for-each node berasal dari parameter input loopDataArray, yang harus diikat ke parameter outputs dari assignment node hulu. Jika Anda menjalankan for-each node 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. Periksa output Anda:

    • 1. Apakah berupa string tunggal tanpa pembatas?

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