MaxCompute的UDF包括UDF、UDAF和UDTF三種函數。通常情況下,這三種函數被統稱為UDF。
實現JAVA UDF使用Maven的使用者可以從
Maven庫中搜尋
odps-sdk-udf擷取不同版本的Java SDK,相關配置資訊如下所示:
<dependency>
<groupId>com.aliyun.odps</groupId>
<artifactId>odps-sdk-udf</artifactId>
<version>0.20.7</version>
</dependency>
通常情況下,JAVA UDF的開發可以通過以下幾種方式:
- 使用MaxCompute Studio完成JAVA UDF開發整個流程。
- 使用Eclipse外掛程式開發和調試JAVA UDF,匯出Jar包,然後通過命令或者DataWorks添加資源後再註冊函數。
本文中會分別給出UDF、UDAF、UDTF的程式碼範例,並通過兩種方式給出開發UDF完整流程步驟樣本(UDAF、UDTF操作步驟與UDF操作步驟一樣)。
UDF樣本
下面將為您介紹一個字元小寫轉換功能的UDF實現樣本。
- 使用MaxCompute Studio開發
- 準備工具環境並建立Java Module。
這裡假設已經完成環境準備,包括安裝Studio並在Studio上建立MaxCompute項目連結以及建立MaxCompute Java Module。
- 編寫代碼。
在配置好的Java Module下建立Java檔案。
直接選擇MaxCompute Java,然後在name一欄裡輸入package名稱.檔案名稱
,Kind選擇UDF。 之後編輯如下代碼:package <package名稱>; import com.aliyun.odps.udf.UDF; public final class Lower extends UDF { public String evaluate(String s) { if (s == null) { return null; } return s.toLowerCase(); } }
说明 若需本地調試java udf,請參見開發和調試UDF - 註冊MaxCompute UDF。
如下圖所示,按右鍵UDF的Java檔案,選擇 Deploy to server,彈框裡選擇註冊到那個MaxCompute project,輸入
function name
,Resource name也可以修改。
填寫好後,單擊 OK即可。註冊成功後會有提示。 - 試用UDF。
- 準備工具環境並建立Java Module。
- 使用Eclipse外掛程式開發
- 建立工程
此處假設已經在Eclipse外掛程式建立好一個MaxCompute(原名ODPS)工程,詳情請參見建立MaxCompute工程。
- 編寫代碼
按照MaxCompute UDF架構的規定,實現函數功能,並進行編譯。樣本如下:
package <package名稱>; import com.aliyun.odps.udf.UDF; public final class Lower extends UDF { public String evaluate(String s) { if (s == null) { return null; } return s.toLowerCase(); } }
將這個Jar包命名為 my_lower.jar。说明- 更詳細的開發調試代碼的介紹請參見UDF開發外掛程式介紹。
- SDK的使用資訊請參見UDF SDK 。
- 添加資源
在運行UDF之前,必須指定引用的UDF代碼。代碼通過資源的形式添加到MaxCompute中。Java UDF必須被打成Jar包,以Jar資源添加到MaxCompute中,UDF架構會自動載入Jar包,運行使用者自訂的UDF。说明 MaxCompute MapReduce也用到了資源這一特有概念,MapReduce文檔中對資源的使用也有闡述。執行如下命令:
add jar my_lower.jar; -- 如果存在同名的資源請將這個jar包重新命名 -- 並注意修改下面樣本命令中相關jar包的名字 -- 又或者直接使用-f選項覆蓋原有的jar資源
- 註冊UDF函數
Jar包被上傳後,使得MaxCompute有條件自動擷取代碼並運行。但此時仍然無法使用這個UDF,因為MaxCompute中並沒有關於這個UDF的任何資訊。因此需要在MaxCompute中註冊一個唯一的函數名,並指定這個函數名與哪個jar資源的哪個類對應。
執行如下命令:CREATE FUNCTION test_lower AS org.alidata.odps.udf.examples.Lower USING my_lower.jar;
- 在SQL中使用此函數進行驗證:
select test_lower('A') from my_test_table;
- 建立工程
UDAF樣本
UDAF的註冊方式與UDF基本相同,使用方式與內建函數中的彙總函式相同。計算平均值的UDAF的程式碼範例,如下所示:
package org.alidata.odps.udf.examples;
import com.aliyun.odps.io.LongWritable;
import com.aliyun.odps.io.Text;
import com.aliyun.odps.io.Writable;
import com.aliyun.odps.udf.Aggregator;
import com.aliyun.odps.udf.UDFException;
/**
* project: example_project
* table: wc_in2
* partitions: p2=1,p1=2
* columns: colc,colb,cola
*/
public class UDAFExample extends Aggregator {
@Override
public void iterate(Writable arg0, Writable[] arg1) throws UDFException {
LongWritable result = (LongWritable) arg0;
for (Writable item : arg1) {
Text txt = (Text) item;
result.set(result.get() + txt.getLength());
}
}
@Override
public void merge(Writable arg0, Writable arg1) throws UDFException {
LongWritable result = (LongWritable) arg0;
LongWritable partial = (LongWritable) arg1;
result.set(result.get() + partial.get());
}
@Override
public Writable newBuffer() {
return new LongWritable(0L);
}
@Override
public Writable terminate(Writable arg0) throws UDFException {
return arg0;
}
}
UDTF樣本
UDTF的註冊和使用方式與UDF相同。程式碼範例如下:
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);
}
}
}
MaxCompute提供了很多內建函數來滿足您的計算需求,同時您還可以通過建立自訂函數來滿足不同的計算需求。詳情請參見建立自訂函數。