Fenriswolf 程式筆記

奮利斯狼的地盤,小綿羊勿入

自訂 Pig Eval Function – 基礎篇

Pig 預設提供的 functions 很少,一般常見的 utility functions 都沒有包含在內
使用自訂的 UDF 有兩種方式

  1. 利用 Pig 內建的 Dynamic Invoke function
  2. 自己寫 UDF


1. Dynamic Invoke
Pig 內建有提供幾種不同 type 的 invoke function 讓大家可以方便的存取自訂的 utility classes.

  1. InvokeForDouble
  2. InvokeForFloat
  3. InvokeForInt
  4. InvokeForLong
  5. InvokeForString

先寫一個簡單的文字檔 number.txt

1
2
3
4
5

如果要使用 java.lang.Math 的 pow function 計算每個值的平方
用 DEFINE 關鍵字註冊 Math static pow function
第一個參數是 class name 及 function 的名稱
第二個參數是 function 的參數個數及型別, 目前提供 string, int, long, float, double, string[], int[], long[], float[] 和 double[] 幾個型別
傳入時的型別名稱不分大小寫

DEFINE POW InvokeForDouble('java.lang.Math.pow', 'double double');
A = LOAD 'number.txt' USING PigStorage() as (num: double);
B = FOREACH A GENERATE POW(num, (double)2);
DUMP B;

這是計算的結果

(1.0)
(4.0)
(9.0)
(16.0)
(25.0)

 
 
2. 寫 UDF
以下的 Matches 範例會以 regular expression 的表達式提供 string match 的功能
先來看直接寫 java matches function 會怎麼寫

public boolean matches(String value, String regex) {
    if(value == null) {
        return false;
    } else {
        return value.matches(regex);
    }
}

轉成 Pig UDF 的方法很簡單
一般的 Pig UDF 會繼承 org.apache.pig.EvalFunc class,但因為 Matches function 是用在 FILTER expression,所以改繼承 org.apache.pig.FilterFunc
其實 FilterFunc 也只是繼承 EvalFunc<Boolean>,直接繼承 FilterFunc 不過是少宣告 Boolean 型別而已

@Override
public Boolean exec(Tuple input) throws IOException {
    if (input == null || input.size() < 2) {
        return false;
    }

    try {
        String value = (String) input.get(0);
        String regex = (String) input.get(1);

        if (value == null) {
            return false;
        } else {
            return value.matches(regex);
        }
    } catch (ExecException ee) {
        throw ee;
    }
}

以 java function 和 Pig UDF 比較一下就會發現
java function 傳參數的方式在 Pig 裡都是用 Tuple object 傳入,只要根據 index 取值即可

把 UDF 包成 udf.jar 就可以在 Pig 內註冊及使用了
以下是讀取 /etc/passwd 中 nologin user 的例子

register udf.jar;
A = LOAD '/etc/passwd' using PigStorage(':') as (username:chararray, password:chararray, uid:int, gid:int, description:chararray, homedir:chararray, loginshell:chararray);
B = FILTER A BY com.fw.pig.Matches(loginshell, '.*nologin');
DUMP B;

DUMP 的結果

(ftp,x,14,50,FTP User,/var/ftp,/sbin/nologin)
(zookeeper,x,495,493,ZooKeeper,/var/run/zookeeper,/sbin/nologin)
(hbase,x,494,492,HBase,/var/run/hbase,/sbin/nologin)
(hive,x,492,490,Hive,/var/lib/hive,/sbin/nologin)

 
 
執行環境
CentOS 6.2
JDK 1.6.0_31
Cloudera CDH3U3
Pig 0.9.2

參考資料
Apache Pig Getting Started
Pig Latin Basics
Built In Functions

程式下載
Matches.java

廣告

2012/03/26 - Posted by | Pig | ,

仍無迴響。

發表迴響

在下方填入你的資料或按右方圖示以社群網站登入:

WordPress.com Logo

您的留言將使用 WordPress.com 帳號。 登出 / 變更 )

Twitter picture

您的留言將使用 Twitter 帳號。 登出 / 變更 )

Facebook照片

您的留言將使用 Facebook 帳號。 登出 / 變更 )

Google+ photo

您的留言將使用 Google+ 帳號。 登出 / 變更 )

連結到 %s

%d 位部落客按了讚: