Java'da kullanıcı tanımlı tablo işlevi (UDTF) yazmak, karmaşık veri işleme görevlerini yönetmek ve özel mantık uygulamak için etkili bir yöntemdir. Java dilinin özelliklerinden yararlanarak belirli veri işleme gereksinimlerinizi daha iyi karşılayabilir; hem geliştirme verimliliğini hem de işlem performansını artırabilirsiniz. Bu konuda Java UDTF'lerinin kod yapısı, kullanımı ve örnekleri açıklanmaktadır.
UDTF kod yapısı
UDTF kodlarını IntelliJ IDEA (Maven) veya MaxCompute Studio kullanarak Java ile yazabilirsiniz. Kod aşağıdaki bileşenleri içermelidir:
-
Java paketi: İsteğe bağlı.
Java sınıflarınızı bulmayı ve kullanmayı kolaylaştırmak için bir paket altında düzenleyebilirsiniz.
-
UDTF sınıfını genişletme: Zorunlu.
Gerekli sınıflar şunlardır:
com.aliyun.odps.udf.UDTF,com.aliyun.odps.udf.annotation.Resolve(@Resolveek açıklaması için) vecom.aliyun.odps.udf.UDFException(Java sınıfındaki yöntemler için). Diğer UDTF sınıflarına veya karmaşık veri türlerine ihtiyacınız varsa gerekli sınıfları MaxCompute UDF genel bakış bölümüne göre ekleyin. -
Özel Java sınıfı: Zorunlu.
Bu, UDTF kodunun organizasyon birimidir. İş mantığınızı uygulayan değişkenleri ve yöntemleri tanımlar.
-
@Resolveek açıklaması: Zorunlu.Biçimi
@Resolve(<signature>)şeklindedir.signatureparametresi, girdi parametrelerinin ve dönüş değerinin veri türlerini tanımlayan bir işlev imzasıdır. Bir UDTF, yansıma yoluyla işlev imzasını alamaz; bunu belirtmek için@Resolveek açıklamasını kullanmalıdır. Örneğin:@Resolve("smallint->varchar(10)").@Resolveek açıklaması hakkında daha fazla bilgi için bkz. @Resolve ek açıklaması. -
Java sınıfında yöntemleri uygulama: Zorunlu.
Java sınıfı uygulaması aşağıdaki dört yöntemi içerir. Bunları ihtiyaçlarınıza göre seçerek uygulayabilirsiniz.
API
Açıklama
public void setup(ExecutionContext ctx) throws UDFExceptionBaşlatma yöntemidir. MaxCompute, UDTF girdi verilerini işlemeye başlamadan önce özel başlatma mantığınızı çağırır.
setupyöntemi işçi başına bir kez çağrılır.public void process(Object[] args) throws UDFExceptionprocessişlevi, bir SQL sorgusundaki her kayıt için bir kez çağrılır.processişlevinin parametreleri, SQL deyimi içinde UDTF için belirtilen girdi parametreleridir. Girdi parametreleri birObject[]dizisi olarak iletilir ve çıktı,forwardişlevi kullanılarak oluşturulur. Çıktıyı belirlemek içinprocessişlevi içindeforwardişlevini çağırmanız gerekir.Notprocessveya close yöntemindenforwardçağrısı yapılmaması veri kaybına neden olabilir. Örneğin, arka plan iş parçacığı birforwardçağrısı yürütürse veri kaybını önlemek içinforwardçağrısı tamamlanana kadarprocessyönteminin bitmemesini sağlamalısınız.public void close() throws UDFExceptionUDTF'nin sonlandırma yöntemidir. Yalnızca bir kez, son kayıt işlendikten sonra çağrılır.
public void forward(Object …o) throws UDFExceptionVeri çıkışı yapmak için
forwardyöntemini çağırın; burada herforwardçağrısı bir kayıt çıkarır. Bir SQL sorgusunda UDTF çağırırkenasyan tümcesini kullanarakforwardçıktısını yeniden adlandırabilirsiniz.Java UDTF yazarken Java Type veya Java Writable Type kullanabilirsiniz. MaxCompute tarafından desteklenen veri türleri ile Java veri türleri arasındaki ayrıntılı eşleme için bkz. Veri türleri.
Aşağıda örnek bir UDTF verilmiştir.
// Organize the defined Java class in the org.alidata.odps.udtf.examples package.
package org.alidata.odps.udtf.examples;
// Extend the UDTF class.
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;
// Custom Java class.
//@Resolve annotation.
@Resolve("string,bigint->string,bigint")
public class MyUDTF extends UDTF {
// Implement the methods of the Java class.
@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);
}
}
}
Sınırlamalar
İnternet erişimi: UDF'ler varsayılan olarak İnternet'e erişemez. İnternet erişimini etkinleştirmek için ağ bağlantısı başvuru formunu doldurun. Onayın ardından MaxCompute teknik destek ekibi bağlantıyı kurmak için sizinle iletişime geçecektir. Ayrıntılar için bkz. Ağ bağlantısı süreci.
-
Aynı
SELECTiçinde başka sütun olmamalı: UDTF çağıran birSELECTdeyimi diğer sütunlara veya ifadelere başvuramaz. Aşağıdaki deyim geçersizdir:-- Invalid: mixes a UDTF with another column select value, user_udtf(key) as mycol ... -
İç içe geçme yok: UDTF'ler diğer UDTF'lerin içinde iç içe geçemez. Aşağıdaki deyim geçersizdir:
-- Invalid: user_udtf2 is nested inside user_udtf1 select user_udtf1(user_udtf2(key)) as mycol...; -
GROUP BY,DISTRIBUTE BYveSORT BYile uyumsuzluk: Bir UDTF, bu yan tümcelerle aynıSELECTdeyimi içinde yer alamaz. Aşağıdaki deyim geçersizdir:-- Invalid: UDTF used with GROUP BY select user_udtf(key) as mycol ... group by mycol;
Dikkat edilmesi gerekenler
Java UDTF yazarken aşağıdakilere dikkat edin:
Farklı UDTF JAR paketlerinde aynı ada sahip ancak farklı uygulama mantığına sahip sınıflar tanımlamaktan kaçının. Örneğin, UDTF1 ve UDTF2'nin sırasıyla udtf1.jar ve udtf2.jar JAR paketi kaynaklarına karşılık geldiğini varsayalım. Her iki JAR paketi de farklı mantığa sahip
com.aliyun.UserFunction.classadlı bir sınıf içeriyorsa aynı SQL deyimi içinde UDTF1 ve UDTF2 çağrıldığında MaxCompute sınıflardan birini rastgele yükler. Bu durum beklenmeyen sonuçlara veya derleme hatalarına yol açabilir.Girdi parametreleri ve dönüş değerleri ilkel türler yerine
StringveLonggibi Java nesne türlerini kullanmalıdır.Bunun nedeni SQL
NULLdeğerlerinin Javanullolarak iletilmesidir ve ilkel türler bunu temsil edemez.
@Resolve ek açıklaması
@Resolve ek açıklamasının biçimi aşağıdaki gibidir.
@Resolve(<signature>)
signature dizesi, UDTF'nin girdi parametrelerinin ve dönüş değerlerinin veri türlerini belirtir. Sorgu ayrıştırma sırasında MaxCompute çağrıları bu imzaya göre doğrular ve tür uyuşmazlığı bulunursa hata bildirir. Biçimi aşağıdaki gibidir.
'arg_type_list -> type_list'
Burada:
type_list: Dönüş değerlerinin veri türlerini temsil eder. Bir UDTF birden çok sütun döndürebilir. Desteklenen veri türleri BIGINT, STRING, DOUBLE, BOOLEAN, DATETIME, DECIMAL, FLOAT, BINARY, DATE, DECIMAL(precision,scale), karmaşık veri türleri (ARRAY, MAP, STRUCT) ve iç içe geçmiş karmaşık veri türleridir.-
arg_type_list: Girdi parametrelerinin veri türlerini temsil eder. Birden çok girdi parametresi virgülle (,) ayrılarak belirtilebilir. Desteklenen veri türleri BIGINT, STRING, DOUBLE, BOOLEAN, DATETIME, DECIMAL, FLOAT, BINARY, DATE, DECIMAL(precision,scale), CHAR, VARCHAR, karmaşık veri türleri (ARRAY, MAP, STRUCT) ve iç içe geçmiş karmaşık veri türleridir.arg_type_listayrıca yıldız işareti (*) veya boş dize ('') destekler.arg_type_listbir yıldız işareti (*) ise işlevin herhangi bir sayıda girdi parametresini kabul ettiği anlamına gelir.arg_type_listboş bir dize ('') ise işlevin girdi parametresi olmadığı anlamına gelir.
Resolve ek açıklamasının genişletilmiş sözdizimi hakkında daha fazla bilgi için bkz. UDAF'ler ve UDTF'ler için dinamik parametreler.
Aşağıdaki tabloda geçerli @Resolve ek açıklamalarına örnekler gösterilmektedir.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Veri türleri
MaxCompute tarafından desteklenen veri türleri veri türü sürümüne göre değişir. MaxCompute 2.0'dan itibaren ARRAY, MAP ve STRUCT gibi karmaşık türler dahil olmak üzere ek veri türleri kullanılabilir. Daha fazla bilgi için bkz. Veri türü sürümleri.
Java UDTF yazarken kullandığınız veri türlerinin MaxCompute tarafından desteklenenlerle doğru şekilde eşleştiğinden emin olun. Aşağıdaki tabloda bu eşlemeler açıklanmaktadır.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
UDTF girdisi veya dönüş değerleri için Java Writable Types kullanmak üzere MaxCompute projenizin MaxCompute 2.0 veri türü sürümünü kullanması gerekir.
Kullanım
geliştirme sürecini izleyerek bir Java UDTF geliştirdikten sonra bunu MaxCompute SQL içinde çağırabilirsiniz.
MaxCompute projesinde UDF kullanma: Yöntem, yerleşik işlevleri kullanmaya benzer. Kullanıcı tanımlı bir işlevi, yerleşik bir işlevi kullandığınız şekilde kullanabilirsiniz.
Projeler arasında UDF kullanma: Proje A'da Proje B'nin UDF'sini kullanma. Aşağıdaki deyim bir örneği göstermektedir:
select B:udf_in_other_project(arg0, arg1) as res from table_t;. Projeler arası paylaşım hakkında daha fazla bilgi için bkz. Paketlere dayalı projeler arası kaynak erişimi.
MaxCompute Studio kullanarak Java UDTF geliştirme ve çağırma konusunda eksiksiz bir adım adım kılavuz için bkz. Kullanım örneği.
Kullanım örneği
Aşağıdaki yordam, MaxCompute Studio kullanarak Java UDTF geliştirme ve çağırma sürecinde size rehberlik eder:
-
Ortamı hazırlayın.
MaxCompute Studio'da UDF geliştirmeden ve hata ayıklamadan önce MaxCompute Studio'yu yüklemeniz ve bir MaxCompute projesine bağlamanız gerekir. Daha fazla bilgi için aşağıdaki konulara bakın:
-
UDTF kodunu yazın.
Project gezgininde modülün kaynak kodu dizinine () sağ tıklayın ve öğesini seçin.
-
Create new MaxCompute java class iletişim kutusunda UDTF öğesine tıklayın, bir Name girin ve Enter tuşuna basın. Örneğin, Java sınıfına MyUDTF adını verin.
Name, oluşturulacak MaxCompute Java sınıfının adıdır. Bir paket oluşturulmadıysa otomatik olarak bir paket oluşturmak için buraya packagename.classname girebilirsiniz.
-
Kod düzenleyicide aşağıdaki kodu girin. Bu bir UDTF kodu örneğidir.
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 define input and output types, e.g., "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); } } }
-
Kodun beklendiği gibi çalıştığından emin olmak için UDTF'yi yerel olarak çalıştırın ve hata ayıklayın.
Hata ayıklama hakkında daha fazla bilgi için bkz. UDF'yi yerel olarak çalıştırma ve hata ayıklama.
Proje ağacındaki MyUDTF dosyasına sağ tıklayın ve Run 'MyUDTF.main()' öğesini seçin. Run/Debug Configurations iletişim kutusunda MaxCompute project öğesini
local, MaxCompute table öğesiniwc_in2, Table partition öğesinip2=1,p1=2, Table columns öğesinicolc,colb, Download Record limit öğesini100ve Data Column Separator öğesini|olarak ayarlayın. Ardından OK düğmesine tıklayın.NotÖrnek çalıştırma için yukarıdaki parametreleri kullanabilirsiniz.
-
UDTF'yi bir JAR paketine paketleyin, MaxCompute projenize yükleyin ve işlevi kaydedin. Bu örnek için işlevi
user_udtfolarak adlandırın.Paketleme hakkında daha fazla bilgi için bkz. Yordam.
IntelliJ IDEA proje ağacında UDTF Java dosyasına (örneğin, MyUDTF) sağ tıklayın ve Deploy to server... öğesini seçin. Package a jar, submit resource and register function iletişim kutusunda hedef MaxCompute project öğesini seçin, Resource file yolunu onaylayın, Main class öğesini ilgili UDTF sınıfı olarak ayarlayın (örneğin,
org.alidata.odps.udtf.examples.MyUDTF), Function name içinuser_udtfgirin, Force update if already exists öğesini seçin ve dağıtımı tamamlamak için OK düğmesine tıklayın. -
MaxCompute Studio'nun sol gezinme bölmesinde Project Explorer öğesine tıklayın. Hedef MaxCompute projesine sağ tıklayın, MaxCompute istemcisini başlatın ve yeni oluşturulan UDTF'yi çağırmak için bir SQL komutu çalıştırın.
Hedef tablo my_table'ün aşağıdaki verileri içerdiğini varsayalım:
+------------+------------+ | col0 | col1 | +------------+------------+ | A B | 1 | | C D | 2 | +------------+------------+UDTF'yi çağırmak için aşağıdaki SQL komutunu çalıştırın.
select user_udtf(col0, col1) as (c0, c1) from my_table;Aşağıdaki sonuç döndürülür.
+----+------------+ | c0 | c1 | +----+------------+ | A | 1 | | B | 1 | | C | 2 | | D | 2 | +----+------------+
İlgili belgeler
Java UDTF'lerinin daha fazla kullanım örneği için bkz. Java UDTF örnekleri.