Menulis fungsi tabel yang didefinisikan pengguna (UDTF) dalam Java merupakan cara efektif untuk menangani tugas pemrosesan data yang kompleks dan menerapkan logika kustom. Dengan memanfaatkan fitur-fitur bahasa Java, Anda dapat lebih baik memenuhi kebutuhan pemrosesan data tertentu, meningkatkan efisiensi pengembangan dan kinerja pemrosesan. Topik ini menjelaskan struktur kode, penggunaan, dan contoh Java UDTF.
Struktur kode UDTF
Anda dapat menulis kode UDTF dalam Java menggunakan IntelliJ IDEA (Maven) atau MaxCompute Studio. Kode tersebut harus mencakup komponen-komponen berikut:
-
Paket Java: Opsional.
Anda dapat mengorganisasi kelas-kelas Java ke dalam paket agar lebih mudah ditemukan dan digunakan.
-
Perluas kelas UDTF: Wajib.
Kelas-kelas yang diperlukan adalah
com.aliyun.odps.udf.UDTF,com.aliyun.odps.udf.annotation.Resolve(untuk anotasi@Resolve), dancom.aliyun.odps.udf.UDFException(untuk metode dalam kelas Java). Jika Anda perlu menggunakan kelas UDTF lain atau tipe data kompleks, tambahkan kelas yang diperlukan sesuai dengan Ikhtisar UDF MaxCompute. -
Kelas Java kustom: Wajib.
Ini adalah unit organisasi untuk kode UDTF. Kelas ini mendefinisikan variabel dan metode yang mengimplementasikan logika bisnis Anda.
-
Anotasi
@Resolve: Wajib.Formatnya adalah
@Resolve(<signature>).signatureadalah signature fungsi yang mendefinisikan tipe data parameter input dan nilai kembali. UDTF tidak dapat memperoleh signature fungsi melalui refleksi dan harus menggunakan anotasi@Resolveuntuk menentukannya, misalnya@Resolve("smallint->varchar(10)"). Untuk informasi lebih lanjut tentang anotasi@Resolve, lihat Anotasi @Resolve. -
Implementasikan metode dalam kelas Java: Wajib.
Implementasi kelas Java mencakup empat metode berikut. Anda dapat memilih untuk mengimplementasikannya sesuai kebutuhan.
API
Deskripsi
public void setup(ExecutionContext ctx) throws UDFExceptionMetode inisialisasi. MaxCompute memanggil logika inisialisasi kustom Anda sebelum UDTF mulai memproses data masukan. Metode
setupdipanggil sekali per worker.public void process(Object[] args) throws UDFExceptionFungsi
processdipanggil sekali untuk setiap catatan dalam kueri SQL. Parameter fungsiprocessadalah parameter input yang ditentukan untuk UDTF dalam pernyataan SQL. Parameter input dilewatkan sebagai arrayObject[], dan output dihasilkan dengan menggunakan fungsiforward. Anda harus memanggil fungsiforwarddi dalam fungsiprocessuntuk menentukan output.CatatanGagal memanggil
forwarddari metodeprocessatau close dapat menyebabkan kehilangan data. Misalnya, jika thread latar belakang mengeksekusi panggilanforward, Anda harus memastikan metodeprocesstidak selesai hingga panggilanforwardselesai untuk mencegah kehilangan data.public void close() throws UDFExceptionMetode terminasi untuk UDTF. Metode ini dipanggil hanya sekali, setelah catatan terakhir diproses.
public void forward(Object …o) throws UDFExceptionPanggil metode
forwarduntuk menghasilkan output data, di mana setiap pemanggilanforwardmenghasilkan satu catatan. Saat Anda memanggil UDTF dalam kueri SQL, Anda dapat menggunakan klausaasuntuk mengganti nama output dariforward.Saat menulis Java UDTF, Anda dapat menggunakan Java Type atau Java Writable Type. Untuk pemetaan detail antara tipe data yang didukung oleh MaxCompute dan tipe data Java, lihat Tipe data.
Berikut ini adalah contoh UDTF.
// Mengorganisasi kelas Java yang didefinisikan dalam paket org.alidata.odps.udtf.examples.
package org.alidata.odps.udtf.examples;
// Memperluas kelas UDTF.
import com.aliyun.odps.udf.UDTF;
import com.aliyun.odps.udf.UDTFCollector;
import com.aliyun.odps.udf.annotation.Resolve;
import com.aliyun.odps.udf.UDFException;
// Kelas Java kustom.
//@Resolve annotation.
@Resolve("string,bigint->string,bigint")
public class MyUDTF extends UDTF {
// Mengimplementasikan metode kelas Java.
@Override
public void process(Object[] args) throws UDFException {
String a = (String) args[0];
Long b = (Long) args[1];
for (String t: a.split("\\s+")) {
forward(t, b);
}
}
}
Batasan
-
Akses Internet: Secara default, UDF tidak dapat mengakses Internet. Untuk mengaktifkan akses Internet, isi formulir permohonan koneksi jaringan. Setelah disetujui, tim dukungan teknis MaxCompute akan menghubungi Anda untuk menyiapkan koneksi tersebut. Untuk detailnya, lihat Proses koneksi jaringan.
-
Tidak ada kolom lain dalam `SELECT` yang sama: Pernyataan
SELECTyang memanggil UDTF tidak dapat mereferensikan kolom atau ekspresi lain. Pernyataan berikut tidak valid:-- Tidak valid: mencampur UDTF dengan kolom lain select value, user_udtf(key) as mycol ... -
Tidak boleh bersarang: UDTF tidak dapat disarangkan di dalam UDTF lain. Pernyataan berikut tidak valid:
-- Tidak valid: user_udtf2 disarangkan di dalam user_udtf1 select user_udtf1(user_udtf2(key)) as mycol...; -
Tidak kompatibel dengan `GROUP BY`, `DISTRIBUTE BY`, dan `SORT BY`: UDTF tidak dapat muncul dalam pernyataan
SELECTyang sama dengan klausa-klausa tersebut. Pernyataan berikut tidak valid:-- Tidak valid: UDTF digunakan dengan GROUP BY select user_udtf(key) as mycol ... group by mycol;
Pertimbangan
Saat menulis Java UDTF, perhatikan hal-hal berikut:
-
Hindari mendefinisikan kelas yang memiliki nama sama tetapi logika implementasi berbeda dalam paket JAR UDTF yang berbeda. Misalnya, asumsikan UDTF1 dan UDTF2 masing-masing berkorespondensi dengan sumber daya paket JAR udtf1.jar dan udtf2.jar. Jika kedua paket JAR tersebut berisi kelas bernama
com.aliyun.UserFunction.classdengan logika berbeda, MaxCompute akan memuat salah satu kelas secara acak saat UDTF1 dan UDTF2 dipanggil dalam pernyataan SQL yang sama. Hal ini dapat menyebabkan hasil tak terduga atau kegagalan kompilasi. -
Parameter input dan nilai kembali harus menggunakan tipe objek Java, seperti
StringdanLong, bukan tipe primitif. -
Hal ini karena nilai
NULLSQL dilewatkan sebagainullJava, yang tidak dapat direpresentasikan oleh tipe primitif.
Anotasi @Resolve
Format anotasi @Resolve adalah sebagai berikut.
@Resolve(<signature>)
String signature menentukan tipe data parameter input dan nilai kembali UDTF. Selama penguraian kueri, MaxCompute memvalidasi pemanggilan terhadap signature ini dan melaporkan error jika ditemukan ketidakcocokan tipe. Formatnya adalah sebagai berikut.
'arg_type_list -> type_list'
Keterangan:
-
type_list: Mewakili tipe data nilai kembali. UDTF dapat mengembalikan beberapa kolom. Tipe data yang didukung adalah BIGINT, STRING, DOUBLE, BOOLEAN, DATETIME, DECIMAL, FLOAT, BINARY, DATE, DECIMAL(precision,scale), tipe data kompleks (ARRAY, MAP, STRUCT), dan tipe data kompleks bersarang. -
arg_type_list: Mewakili tipe data parameter input. Beberapa parameter input dapat ditentukan, dipisahkan dengan koma (,). Tipe data yang didukung adalah BIGINT, STRING, DOUBLE, BOOLEAN, DATETIME, DECIMAL, FLOAT, BINARY, DATE, DECIMAL(precision,scale), CHAR, VARCHAR, tipe data kompleks (ARRAY, MAP, STRUCT), dan tipe data kompleks bersarang.arg_type_listjuga mendukung tanda bintang (*) atau string kosong ('').-
Jika
arg_type_listadalah tanda bintang (*), artinya fungsi menerima jumlah parameter input apa pun. -
Jika
arg_type_listadalah string kosong (''), artinya fungsi tidak memiliki parameter input.
Untuk informasi lebih lanjut tentang sintaksis ekstensi anotasi Resolve, lihat Parameter dinamis untuk UDAF dan UDTF.
-
Tabel berikut menunjukkan contoh anotasi @Resolve yang valid.
|
Contoh |
Deskripsi |
|
|
Tipe parameter input adalah BIGINT dan BOOLEAN. Tipe nilai kembali adalah STRING dan DATETIME. |
|
|
Fungsi menerima jumlah parameter input apa pun. Tipe nilai kembali adalah STRING dan DATETIME. |
|
|
Fungsi tidak memiliki parameter input. Tipe nilai kembali adalah DOUBLE, BIGINT, dan STRING. |
|
|
Tipe parameter input adalah ARRAY, STRUCT, dan STRING. Tipe nilai kembali adalah MAP dan STRUCT. |
Tipe data
Tipe data yang didukung oleh MaxCompute bervariasi berdasarkan edisi tipe data. Mulai dari MaxCompute 2.0, tersedia tipe data tambahan, termasuk tipe kompleks seperti ARRAY, MAP, dan STRUCT. Untuk informasi lebih lanjut, lihat Edisi tipe data.
Saat menulis Java UDTF, pastikan tipe data yang Anda gunakan dipetakan dengan benar ke tipe data yang didukung oleh MaxCompute. Tabel berikut menjelaskan pemetaan tersebut.
Tipe MaxCompute | Tipe Java | Tipe Java Writable |
TINYINT | java.lang.Byte | ByteWritable |
SMALLINT | java.lang.Short | ShortWritable |
INT | java.lang.Integer | IntWritable |
BIGINT | java.lang.Long | LongWritable |
FLOAT | java.lang.Float | FloatWritable |
DOUBLE | java.lang.Double | DoubleWritable |
DECIMAL | java.math.BigDecimal | BigDecimalWritable |
BOOLEAN | java.lang.Boolean | BooleanWritable |
STRING | java.lang.String | Text |
VARCHAR | com.aliyun.odps.data.Varchar | VarcharWritable |
BINARY | com.aliyun.odps.data.Binary | BytesWritable |
DATE | java.sql.Date | DateWritable |
DATETIME | java.util.Date | DatetimeWritable |
TIMESTAMP | java.sql.Timestamp | TimestampWritable |
INTERVAL_YEAR_MONTH | N/A | IntervalYearMonthWritable |
INTERVAL_DAY_TIME | N/A | IntervalDayTimeWritable |
ARRAY | java.util.List | N/A |
MAP | java.util.Map | N/A |
STRUCT | com.aliyun.odps.data.Struct | N/A |
Untuk menggunakan Java Writable Types sebagai input atau nilai kembali UDTF, proyek MaxCompute Anda harus menggunakan edisi tipe data MaxCompute 2.0.
Penggunaan
Setelah mengembangkan Java UDTF sesuai dengan proses pengembangan, Anda dapat memanggilnya dalam SQL MaxCompute.
Gunakan UDF dalam proyek MaxCompute: Metodenya mirip dengan penggunaan fungsi bawaan. Anda dapat menggunakan fungsi yang didefinisikan pengguna dengan cara yang sama seperti menggunakan fungsi bawaan.
Gunakan UDF lintas proyek: Gunakan UDF dari Proyek B di Proyek A. Contoh pernyataan berikut:
select B:udf_in_other_project(arg0, arg1) as res from table_t;. Untuk informasi lebih lanjut tentang berbagi lintas proyek, lihat Akses resource lintas proyek berbasis paket.
Untuk panduan lengkap mengembangkan dan memanggil Java UDTF menggunakan MaxCompute Studio, lihat Contoh penggunaan.
Contoh penggunaan
Prosedur berikut memandu Anda mengembangkan dan memanggil Java UDTF menggunakan MaxCompute Studio:
Persiapkan lingkungan.
Sebelum Anda dapat mengembangkan dan men-debug UDF di MaxCompute Studio, instal MaxCompute Studio dan hubungkan ke proyek MaxCompute. Untuk informasi lebih lanjut, lihat topik-topik berikut:
-
Tulis kode UDTF.
Pada explorer Project, klik kanan direktori kode sumber modul () dan pilih .
-
Pada kotak dialog Create new MaxCompute java class, klik UDTF, masukkan Name, lalu tekan Enter. Misalnya, beri nama kelas Java tersebut MyUDTF.
Name adalah nama kelas Java MaxCompute yang akan dibuat. Jika paket belum dibuat, Anda dapat memasukkan packagename.classname di sini untuk menghasilkan paket secara otomatis.
-
Pada editor kode, masukkan kode berikut. Ini adalah contoh kode UDTF.
package org.alidata.odps.udtf.examples; import com.aliyun.odps.udf.UDTF; import com.aliyun.odps.udf.UDTFCollector; import com.aliyun.odps.udf.annotation.Resolve; import com.aliyun.odps.udf.UDFException; // TODO tentukan tipe input dan output, misalnya "string,string->string,bigint". @Resolve("string,bigint->string,bigint") public class MyUDTF extends UDTF { @Override public void process(Object[] args) throws UDFException { String a = (String) args[0]; Long b = (Long) args[1]; for (String t: a.split("\\s+")) { forward(t, b); } } }
-
Jalankan dan debug UDTF secara lokal untuk memastikan kode berfungsi sebagaimana mestinya.
Untuk informasi lebih lanjut tentang debugging, lihat Jalankan dan debug UDF secara lokal.
Klik kanan file MyUDTF pada pohon proyek dan pilih Run 'MyUDTF.main()'. Pada kotak dialog Run/Debug Configurations, atur MaxCompute project ke
local, MaxCompute table kewc_in2, Table partition kep2=1,p1=2, Table columns kecolc,colb, Download Record limit ke100, dan Data Column Separator ke|. Lalu, klik OK.CatatanAnda dapat menggunakan parameter di atas untuk menjalankan contoh.
-
Kemas UDTF ke dalam paket JAR, unggah ke proyek MaxCompute Anda, dan daftarkan fungsinya. Untuk contoh ini, beri nama fungsi
user_udtf.Untuk informasi lebih lanjut tentang pengemasan, lihat Prosedur.
Pada pohon proyek IntelliJ IDEA, klik kanan file Java UDTF (misalnya, MyUDTF) dan pilih Deploy to server.... Pada kotak dialog Package a jar, submit resource and register function, pilih MaxCompute project target, konfirmasi path Resource file, atur Main class ke kelas UDTF yang sesuai (misalnya,
org.alidata.odps.udtf.examples.MyUDTF), masukkanuser_udtfuntuk Function name, pilih Force update if already exists, lalu klik OK untuk menyelesaikan penerapan. -
Pada panel navigasi kiri MaxCompute Studio, klik Project Explorer. Klik kanan proyek MaxCompute target, mulai klien MaxCompute, dan jalankan perintah SQL untuk memanggil UDTF yang baru dibuat.
Asumsikan tabel target, my_table, berisi data berikut:
+------------+------------+ | col0 | col1 | +------------+------------+ | A B | 1 | | C D | 2 | +------------+------------+Jalankan perintah SQL berikut untuk memanggil UDTF.
select user_udtf(col0, col1) as (c0, c1) from my_table;Hasil berikut dikembalikan.
+----+------------+ | c0 | c1 | +----+------------+ | A | 1 | | B | 1 | | C | 2 | | D | 2 | +----+------------+
Dokumentasi terkait
Untuk contoh penggunaan Java UDTF lainnya, lihat Contoh Java UDTF.