概述
支持使用 Java、Python、Javascript 三种语言编写 UDF
Java 自定义函数较为成熟,其它两种功能还有限
需要的 jar 包:
/root/training/pig-0.14.0/pig-0.14.0-core-h2.jar
/root/training/pig-0.14.0/lib
/root/training/pig-0.14.0/lib/h2
Pig 函数的类型
自定义过滤函数
自定义运算函数
自定义加载函数
部署自定义函数
注册 jar 包
//语法
register filepath/jarname.jar
//实例
register /root/temp/pig.jar
为自定义函数起别名:
//语法
define functionName FunctionPath;
//实例
define myfilter demo.pig.MyFilterFunction;
自定义过滤函数
package demo.pig;
import java.io.IOException;
import org.apache.pig.FilterFunc;
import org.apache.pig.data.Tuple;
/**
* Pig的自定义过滤函数 过滤员工薪水大于2000的员工
* @author Administrator
*
*/
public class SortSal extends FilterFunc {
@Override
public Boolean exec(Tuple tuple) throws IOException {
//Tuple 表示调用时传递的参数
//取出薪水
int sal = (int) tuple.get(0);
return sal > 2000?true:false;
}
}
使用语法
tablename = filter emp2 by demo.pig.IsSalaryTooHigh(sal);
表名 = filter 要处理的表 by 类路径(参数);
自定义运算函数
package demo.pig;
import java.io.IOException;
import org.apache.pig.EvalFunc;
import org.apache.pig.data.Tuple;
/**
* Pig的自定义运算函数 根据薪水判断薪水的水平
* @author Administrator
*
*/
public class CheckSalaryGrade extends EvalFunc<String> {
@Override
public String exec(Tuple tuple) throws IOException {
//Tuple 为调用参数时 传递的值
int sal = (int) tuple.get(0);
if(sal < 1000) {
return "Grade A";
}
else if(sal >= 1000 && sal <=2000) {
return "Grade B";
}
else {
return "Grade C";
}
}
}
使用语法
my2 = foreach emp2 generate ename,sal,demo.pig.CheckSalaryGrade(sal);
自定义加载函数
package demo.pig;
import java.io.IOException;
import org.apache.hadoop.mapreduce.InputFormat;
import org.apache.hadoop.mapreduce.Job;
import org.apache.hadoop.mapreduce.RecordReader;
import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
import org.apache.hadoop.mapreduce.lib.input.TextInputFormat;
import org.apache.pig.LoadFunc;
import org.apache.pig.backend.hadoop.executionengine.mapReduceLayer.PigSplit;
import org.apache.pig.data.BagFactory;
import org.apache.pig.data.DataBag;
import org.apache.pig.data.Tuple;
import org.apache.pig.data.TupleFactory;
/**
* Pig的自定义加载函数
* @author Administrator
*
*/
public class MyLoad extends LoadFunc {
//定义一个变量来保存 hdfs的输入流
private RecordReader reader;
/**
* 输入数据的数据格式是什么
*/
public InputFormat getInputFormat() throws IOException {
return new TextInputFormat();
}
/**
* 从数据流中读入数据 如何进行加载,加载完成之后 范湖tuple
*/
public Tuple getNext() throws IOException {
Tuple result = null;
try {
//判断数据流中是否有值
if(!this.reader.nextKeyValue()) {
return result;
}
//读到数据 进行加载
String data = this.reader.getCurrentValue().toString();
//生成结果的Tuple
result = TupleFactory.getInstance().newTuple();
//分词
String[] words = data.split(" ");
//把每个单词放入一个Tuple,再把这些tuple放入一个bag中
//创建一个bag
DataBag bag = BagFactory.getInstance().newDefaultBag();// 生成表
for(String w:words){
//为每个单词生成Tuple
Tuple aTuple = TupleFactory.getInstance().newTuple();
aTuple.append(w);//加入单词
//把aTuple加入表
bag.add(aTuple);
}
//把表放入result的tuple中
result.append(bag);
//对数据进行处理
} catch (Exception e) {
// TODO: handle exception
}
return result;
}
@Override
public void prepareToRead(RecordReader reader, PigSplit arg1) throws IOException {
// 将hdfs的输入流 传递出去
this.reader = reader;
}
/**
* 指定hdfs的输入路径
*/
public void setLocation(String path, Job job) throws IOException {
FileInputFormat.setInputPaths(job,path);
}
}
使用语法
tablename = MyLoad('filepath').....;