14.4 用户定义函数

大家可以使用用户定义函数(User Defined Functions, UDFs)来编写特定的处理函数,这大大地增强了Pig Latin语言的功能,用户可以方便地对其功能进行扩充和完善。Pig为用户定义函数提供了大量的支持,UDFs几乎可以作为Pig所有操作符的一部分来使用。

下面我们将通过一个实例来帮助大家学习如何编写UDFs,以及如何让Pig使用大家编写的UDFs。

这里我们给出一个学生表(学号,姓名,性别,年龄,所在系),其中含有如下几条记录:

201000101:李勇:Boy:20:计算机软件与理论

201000102:王丽:Girl:19:计算机软件与理论

201000103:刘花:Girl:18:计算机应用技术

201000104:李肖:Boy:19:计算机系统结构

201000105:吴达:Boy:19:计算机系统结构

201000106:滑可:Boy:19:计算机系统结构

它们所对应的数据类型如下所示:


Student(Sno:chararray, Sname:chararray, Ssex:chararray, Sage:int, Sdept:chararray)


这里字段与字段之间通过冒号(半角英文标点)隔开,下面我们将编写一个函数,能够将所有的小写字母转换成对应的大写字母。

14.4.1 编写用户定义函数

下面是我们编写的UDFs代码,如代码清单14-1所示。

14.4 用户定义函数 - 图1

代码的第1行表明这个函数是myudfs包的一部分。这个UDF类是EvalFunc类的继承,EvalFunc是所有eval函数的基类。在这个例子中,这个类使用返回值类型为Java String的参数进行参数化。现在我们需要去实现EvalFunc类的exec函数。在这里,函数的输入是一个tuple集合,它们按照Pig脚本加载的顺序依次被调用。每当输入一个tuple, UDF将被调用一次。在我们的例子中,它是一个与学生的性别相一致的字符串域。

我们首先需要做的是处理无效的数据。这依赖于数据的格式,如果数据为字节数组,那就意味着它不需要被转化为其他的数据类型;如果输入的数据为其他类型,那么就需要将数据转换成适当的数据类型;如果输入数据的格式不能被系统识别或转换,NULL值将被返回。这就是我们例子中的第16行会抛出一个错误的原因。在这里,WrappedIOException是一个帮助类,帮助我们把真实的异常转换为IO异常。

另外,注意第10~11行的作用为检查输入数据为null或空。如果为null或空,系统将返回null。

很容易看出,函数的实现部分在第13~14行,它们使用Java函数将接收的输入转换为相应的大写。

如果要使用这个函数,它需要被编译并且包含在一个JAR中。用户需要建立pig.jar来编译用户的UDF。pig.jar文件需要用户自行下载安装。可以使用下面的命令集从SVN库中检验代码并且创建pig.jar文件:


svn co http://svn.apache.org/repos/asf/pig/trunk

cd trunk

ant


注意 在使用svn和ant操作之前,要确保系统已经安装了SVN和ant[1]

上述操作完成之后,用户可以在自己当前的工作目录中看到pig.jar文件(它位于trunk目录下)。

当pig.jar文件创建完成之后,我们首先需要对函数进行编译,然后再创建一个包含这个函数的JAR文件。具体操作命令如下:


cd myudfs

javac-cp pig.jar UPPER.java

cd..

jar-cf myudfs.jar myudfs


[1]这部分知识已经超出了本书的内容,具体的操作大家可以参考其他相关书籍。