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的開發可以通過以下幾種方式:
本文中會分別給出UDF、UDAF、UDTF的程式碼範例,並通過兩種方式給出開發UDF完整流程步驟樣本(UDAF、UDTF操作步驟與UDF操作步驟一樣)。
说明
  • 關於自訂函數註冊和登出、查看函數列表的相關命令語句請參見函數操作
  • Java和MaxCompute的資料類型對應關係,請參見參數與傳回值類型

UDF樣本

下面將為您介紹一個字元小寫轉換功能的UDF實現樣本。
  • 使用MaxCompute Studio開發
    1. 準備工具環境並建立Java Module

      這裡假設已經完成環境準備,包括安裝Studio並在Studio上建立MaxCompute項目連結以及建立MaxCompute Java Module

    2. 編寫代碼
      在配置好的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
    3. 註冊MaxCompute UDF
      如下圖所示,按右鍵UDF的Java檔案,選擇 Deploy to server,彈框裡選擇註冊到那個MaxCompute project,輸入 function name,Resource name也可以修改。

      填寫好後,單擊 OK即可。註冊成功後會有提示。
    4. 試用UDF
      開啟SQL指令碼,執行代碼如 select Lower_test(‘ABC’);結果如下圖所示:

      说明 Studio中編寫SQL指令碼請參見編寫SQL指令碼
  • 使用Eclipse外掛程式開發
    1. 建立工程

      此處假設已經在Eclipse外掛程式建立好一個MaxCompute(原名ODPS)工程,詳情請參見建立MaxCompute工程

    2. 編寫代碼
      按照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
      说明
    3. 添加資源
      在運行UDF之前,必須指定引用的UDF代碼。代碼通過資源的形式添加到MaxCompute中。Java UDF必須被打成Jar包,以Jar資源添加到MaxCompute中,UDF架構會自動載入Jar包,運行使用者自訂的UDF。
      说明 MaxCompute MapReduce也用到了資源這一特有概念,MapReduce文檔中對資源的使用也有闡述。
      執行如下命令:
      add jar my_lower.jar;
      -- 如果存在同名的資源請將這個jar包重新命名
      -- 並注意修改下面樣本命令中相關jar包的名字
      -- 又或者直接使用-f選項覆蓋原有的jar資源
    4. 註冊UDF函數

      Jar包被上傳後,使得MaxCompute有條件自動擷取代碼並運行。但此時仍然無法使用這個UDF,因為MaxCompute中並沒有關於這個UDF的任何資訊。因此需要在MaxCompute中註冊一個唯一的函數名,並指定這個函數名與哪個jar資源的哪個類對應。

      執行如下命令:
      CREATE FUNCTION test_lower AS org.alidata.odps.udf.examples.Lower USING my_lower.jar;
    5. 在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提供了很多內建函數來滿足您的計算需求,同時您還可以通過建立自訂函數來滿足不同的計算需求。詳情請參見建立自訂函數