Pig latin 介绍

加载
默认load 加载PigStorage 加载存放在HDFS中并且以制表键进行分割的文件。
加载HBase 
divs = load ’NYSE_dividends’ using HBaseStorage();

加载HDFS 中,以逗号分割的文件。
divs =  load ’NYSE_dividends’ using PigStorage(‘,’);

HDFS 文件的模式匹配。
PigStorage 和 TextLoader 支持模式匹配。
注意:这些通配符是否可以工作,是由HDFS版本决定的,不是Pig。
存储
默认store 加载PigStorage 将结果 以制表键进行分割的文件存储 HDFS中。
store processed into ‘/tmp/dyf/recommed_user'
存在 /tmp/dyf/recommed_user 目录下,是多个文件,文件个数取决于执行store 前的最后一个任务的并行数。是由Hadoop 决定的,并非Pig。

store processed into ‘/tmp/dyf/recommed_user’ using HBaseStorage()
store processed into ‘/tmp/dyf/recommed_user’ using PigStorage(‘,')
输出
dump processed
关系操作
关系操作符可以对数据:排序,分组,链接,推测和过滤等转换。
foreach
     在数据管道中将一组表达式应用到每一条记录上。
prices = load ’NYSE_daily’ as (exchange,symbol,date,open,hight,low,close,volume,adj_close);
gain = foreach prices generate close - open;
gain2 = foreach prices generate $6 - $3;
all = foreach prices generate *;
使用 * 代表所有字段。
使用 .. 代表字段区间。
beginning = foreach prices generate ..open;
middle = foreach prices generate open..close;
end = foreach prices generate volume..;

null 对所有操作符都是抵消。x + null = null;
三元运算:2 == 2 ? 1 : 4 — 返回 1
                  3 == 2 ? 1 : 4 — 返回 4
                  null == 2 ? 1 : 4 — 返回 null
                  3 == 2 ? 1 : ‘fred' — 类型错误,冒号两边的值应该是同一类型。
投射运算符(从复杂类型中提取值)
map # 投射
tuple . 投射
bball = load ‘baseball’ as (name:chararray,team:chararray,position:bag{t:(p:chararray)},bat:map{});
avg = foreach bball generate bat#’batting_average’;

A = load ‘input’ as (t:tuple(x:int,y:int));
B = foreach A generate t.x, t.$1
如果 t 不存在就报错,如果t.x 不存在返回null

A = load ‘input’ as (b:bag{t(x:int,y:int)});
B = foreach A generate b.x;
B2 = foreach A generate b.(x,y);
注意b.x 是一个bag ,而不是一个可以进行计算的数据值。

A = load ‘foo’ as (x:chararray,y:int,z:int);
B = group A by x; — 产生包含对于 x 给定的值对应所有记录的bag A
C = foreach B generate SUM(A.y + A.z );
这个脚本报错,因为A.y 和 B.y 是 bag。

正确代码
A = load ‘foo’ as (x:chararray,y:int,z:int);
A1 = foreach A generate x, y+z as yz;
B = group A1 by x;
C = foreach B generate SUM(A1.yz)
Filter
filter 包含一个断言,如果断言为true ,那么这条记录会在数据流中下传,否则不会下传。
== , != , > , >= , <= , <
== 和 != 也可以用于map 和 tuple 这样的复杂类型,不可以用于bag。
遵循标准的操作符优先级规则。计算操作符的优先级大于比较操作符。
x + y == a + b 等价于 (x + y)= (a + b)
对于chararray 可以判断是否符合正则表达式。
startswithcm = filter divs by symbol matches ‘CM.*’;
Pig 使用的是Java 的正则表达式,要求整个chararray 匹配。如果要找fred,必须’.*fred.*'
startswithcm = filter divs by not symbol matches ‘CM.*’;
a and b or not c
is null
not is null 
x === 2 只有第一个值为2 可以通过过滤器。
注意:filter 不可在 foreach 中使用。
Group
group 将包含特定的键所有对应的值的所有记录封装到一个bag中。
daily = load ’NEYS_daily’ as (exchange,stock);
grpd = group daily by stock;
cnt =  foreach grpd generate group,COUNT(daily);
group 存放着键 。
bag 的别名和被分组的那条语句的别名相同。
describe grpd
grpd:{group:bytearray,daily:{exchange:bytearray,stock:bytearray}}
多键分组
grpd = group daily by ( exchange , stock );
avg = foreach grpd generate group, AVG(daily.dividends);
describe grpd;
grpd: {group :(exchange:byte array,stock: bytearray),daily:{exchage:bytearray,stock:bytearray,date:bytearray,dividends:bytearray};
对所有字段分组
grpd = group daily by all;
目前为止,group 是第一个会触发reduce 过程的操作符。

对于数据倾斜:某一个reducer 任务非常重。pig 使用Hadoop 的组合器进行reducer 间的负载均衡。并非所有的计算都是可以通过这个组合器完成的。sum,count 可以。
Order by      
daily = load ‘EYSE_daily’ as (symbol:char array,date:chararray);
bydate = order daily by date;
bydate_symbol = order daily by date, symbol desc;
注意:desc 只对symbol 起作用。
bydate_symbol = order daily by date desc , symbol;

Distinct
      只会对这个记录级别去重。
daily = load ’NEYS_daily’ as (exchange:chararay ,symbol:chararray);
uniq = distinct daily;
Join
daily = load ’NEYS_daily’ as (exchange,symbol,date);
divs = load ’NEYS_dividends’ as (exchange,symbol,date);
jnd = join daily by (symbol,date),divs by (symbol,date);
desc jnd
jnd :{daily::exchange:bytearrary,daily::symbol:byte array,daily::date:byte array,divs::symbol:byte array,divs::date:bytearray}

jndout = join daily by(symbol,date) left outer,divs by(symbol,date)
还支持right join 和 full join(outer 可以省略)
对于left outer join,pig 必须知道右边的模式。
null 值不会匹配上任何值。
inner join 会去除所有包含null 键值,outer join null 键值会保留,但是不会和任何值匹配。
A = load ‘input1’ as (x,y);
B = load ‘input2’ as (u,v);
C = load ‘input3’ as (e,f);
alpha = join A by x,B by u ,C by e;
对于每支股票,找出在两个日期范围内股息都是增加的记录
divs1 = load ’NYSE_dividends’ as (symbol,date);
and = join divs1 by symbol,divs1 by symbol;
increased = filter and by divs1::date < divs2::date and divs1::dividends < divs2::dividends;
Limit
divs = load ’NYSE_dividends’;
first10 = limit divs 10;
注意:除了order 外,其他所有操作符pig都不会保证产生的数据是按照一定次序的。
limit 操作符,pig 也会读取全部数据。
Sample(抽取样本)
divs = load ‘NYSE-dividends’;
some = sample divs 0.1;
抽取10%的数据。
等价于
some = filter divs by random()<=0.1;
Parallel 
parallel (pig 告诉用户如何并行的)可以附加到任一个关系符后面,它只会控制reduce阶段的并行,因此只有加到触发reduce的操作符后才有意义。
触发reduce操作符:group,order,distinct,join,cogroup,cross。
在local 模式下parallel 会被忽略,因为local 下所有操作符都是串行。
daily = load ’NYSE_daily’ as (exchange,symbol,date,open,hight,low,close,volume,adj_close);
bysymbol = group daily by symbol parallel 10;
触发10 reducer(只对group其作用)
average = foreach by symbol generate group ,AVG(daily.close) as avg;
sorted = order average by avg desc parallel 2;
全局设置reduser 个数
set default parallel 10;
所有任务触发10reducer。
在MapReduce中,数据是通过一个叫做InputFormat 的类读取的,InputFormat 的部分作用就是告诉MapReduce 需要执行多少个map 任务。虽然Pig不能控制执行多少个map任务,但是他允许用户编写加载函数,用户可以重写和运行自己的InputFormat的方法。

用户自定义函数 UDF
     所有UDF 必须用Java 编写。
注册UDF
register ‘your_path_to_piggybank/piggybank.jar ’;
divs = load ’NYSE_dividends’ as (exchange,symbol,date,dividends);
backwards =foreach divs generate org.apache.pig.piggybank.evaluation.string.Reverse(symbol);

— define 定义别名
register ‘your_path_to_piggybank/piggybank.jar ’;
define reverse  org.apache.pig.piggybank.evaluation.string.Reverse();
divs = load ’NYSE_dividends’ as (exchange,symbol,date,dividends);
backwards =foreach divs generate reverse(symbol);

在pig 命令时指一组路径用于查找需要的UDF
pig -Dudf.import.list org.apache.pig.piggybank.evaluation.string register.pig
register ‘your_path_to_piggybank/piggybank.jar ’;
divs = load ’NYSE_dividends’ as (exchange,symbol,date,dividends);
backwards =foreach divs generate Reverse(symbol);

pig -Dudf.import.list org.apache.pig.piggybank.evaluation.string -Dpig.additional.jars= your_path_to_piggybank/piggybank.jar
divs = load ’NYSE_dividends’ as (exchange,symbol,date,dividends);
backwards =foreach divs generate Reverse(symbol);

pig0.8 版以后,register 命令接受HDFS路径。
pig0.9 版以后,register 命令接受正则匹配。
register ‘/usr/local/share/pig/udfs/*.jar’;

注册Python UDF
python 脚本必须在用户当前目录下。
将udfs/python/production.py 复制到数据目录下。
register ‘production.py’ using python as bballudfs;
player = load ‘baseball’ as (name:char array,team:char array,pos:bag{t:(p:char array)},bat:map[]);
calcprod = foreach  non null generate name,bballudfs.production((float)bat#’slugging_percentage’,(float)bat#’on_base_percentage’);
注意:需要确保jython.jar 已经放到类路中,用户可以通过设置PIG_CLASSPATH 环境变量来指定该路径。
jython.jar 将Python 程序编译成Java程序。
as bballudfs 为加载UDF 定义了一个命名空间。

假设CurrencyConverter 的构造函数需要两个参数,param1:需要被转换的货币类型,param2:需要转换成的货币类型。

register ‘acme.jar’;
define convert com.acme.financial.CurrencyConverter(‘dollar’,’enro’);
divs = load ’NYSE_dividends’ as (exchange:chararray,symbol:chararray,dividends:float);
backwards = foreach divs generate convert(dividends);

调用Java 静态方法
0.8 版开始,Pig 提供invoker 方法使用一些特定的Java静态方法。
所有没有参数或者有int,long,float,double,String,array 的参数,同时有int,long,float,double,String的返回值的Java 方法都可以调用。每一种类型都有一种调用方法:InvokeForInt, InvokeForLong, InvokeForFloat, InvokeForDouble, InvokeForString:第一个参数是完整包名,类名和方法名。
第二参数:以空格分隔参数列表,如果是参数类型是数组 int[]。如果不需要第二个参数,第二参数可以省略。

define hex InvokeForString(‘java.lang.Integer.toHexString’,’int’);
divs = load ’NYSE_daily’ as (exchange,symbol,date,open,hight,low,close,volume,adj_close);
nonnull = fileter divs by volume is not null;
index = foreach nonnull generate symbol,hex((int)volume);

调用Java 方法,是使用放射机制的。付出一些性能上的代价。
当输入参数是null时,调用器函数会抛出 IllegalArgumentException。像上边那样放置一个过滤器避免出现异常。















  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值