玩转大数据系列之Apache Pig高级技能之函数编程(六)

原创不易,转载请务必注明,原创地址,谢谢配合!
http://qindongliang.iteye.com/


Pig系列的学习文档,但愿对你们有用,感谢关注散仙!

Apache Pig的前世此生

Apache Pig如何自定义UDF函数?

Apache Pig5行代码怎么实现Hadoop的WordCount?

Apache Pig入门学习文档(一)

Apache Pig学习笔记(二)

Apache Pig学习笔记以内置函数(三)

玩转大数据系列之Apache Pig如何与Apache Lucene集成(一)

玩转大数据系列之Apache Pig如何与Apache Solr集成(二)

玩转大数据系列之Apache Pig如何与MySQL集成(三)

玩转大数据系列之如何给Apache Pig自定义存储形式(四)

玩转大数据系列之Apache Pig如何经过自定义UDF查询数据库(五)

如何使用Pig集成分词器来统计新闻词频?


bdb45a8c-0783-3da4-81ae-cf969e75f38b.png

在Hadoop的生态系统中,若是咱们要离线的分析海量的数据,大多数人都会选择Apache Hive或Apache Pig,在国内整体来讲,Hive使用的人群占比比较高, 而Pig使用的人相对来讲,则少的多,这并非由于Pig不成熟,不稳定,而是由于Hive提供了类数据库SQL的查询语句,使得大多人上手Hive很是容易,相反而Pig则提供了类Linux shell的脚本语法,这使得大多数人不喜欢使用。

若是在编程界,统计一下会SQL和会shell,那我的数占的比重大,散仙以为,毫无疑问确定是SQL语句了。由于有至关一部分编程人员是不使用Linux的,而是微软的的一套从C#,到ASP.NET,SQL Server再到Windows的专用服务器 。



7c7b3bef-0dda-3ac6-8cdb-1ecc1dd9c194.jpg

OK,扯远了,赶忙回来,使用shell的攻城师们,我以为都会爱上它的,由于在linux系统中,没有比shell更简洁易用了,若是再配上awk和sed更是如虎添翼了。

咱们都知道shell是支持函数调用的,这一点和JavaScript是很是相似的,经过定义函数咱们能够重复使用某个功能,而不用再次大量编码,其中,把变的东西,分离成参数,不变的东西定义成语句,这样以来,就可以下降编码的冗余和复杂性,试想一下,若是Java里,没有方法,那将会是多么难以想象的一件事。

Pig做为类shell的语言,也支持了函数的方式,封装某个功能,以便于咱们重用,这一点相比Hive来讲,是一个很好的优点。

下面先看下定义Pig函数(也叫宏命令)定义的语法:

DEFINE (macros) :
支持的参数:
alias  pig的标量引用
×××(integer)
浮点型(float)
字符串(String)

下面看几个例子,让咱们迅速对它熟悉并掌握,先看下咱们的测试数据:

java

Java代码 复制代码 收藏代码spinner.gifnode

  1. 1,张三,男,23,中国   linux

  2. 2,张三,女,32,法国   shell

  3. 3,小花,男,20,英国   数据库

  4. 4,小红,男,16,中国   编程

  5. 5,小红,女,25,洛阳   服务器

  6. 6,李静,女,25,中国河南安阳   ide

  7. 7,王强,男,11,英国   函数

  8. 8,张飞,男,20,美国  oop

1,张三,男,23,中国
2,张三,女,32,法国
3,小花,男,20,英国
4,小红,男,16,中国
5,小红,女,25,洛阳
6,李静,女,25,中国河南安阳
7,王强,男,11,英国
8,张飞,男,20,美国



再看下pig脚本:

Java代码 复制代码 收藏代码spinner.gif

  1. --定义pig函数1 支持分组统计数量   

  2. DEFINE group_and_count (A,group_key,number_reduces) RETURNS B {   

  3.     

  4.  d = group $A by $group_key parallel $number_reduces;   

  5.     

  6.  $B = foreach d generate group, COUNT($1);   

  7.   

  8. };   

  9.   

  10.   

  11. --定义pig函数2 支持排序   

  12. --A 关系引用标量   

  13. --order_field 排序的字段   

  14. --order_type 排序方式 desc ? asc ?   

  15. --storedir 存储的HDFS路径   

  16. --空返回值   

  17. define my_order(A,order_field,order_type,storedir) returns void {   

  18.     

  19.   d = order $A by $order_field $order_type ;   

  20.   store  d into '$storedir' ;     

  21.     

  22.   

  23. };    

  24.   

  25.   

  26. --定义pig函数3,支持filter过滤,以及宏命令里面调用   

  27.   

  28. --定义过滤操做   

  29. define  myfilter (A,field,count) returns B{   

  30.   

  31.    b= filter $A by $field > $count ;   

  32.   

  33.    $B = group_and_count(b,'sex',1);   

  34.   

  35. };   

  36.   

  37.   

  38. a = load  '/tmp/dongliang/318/person' using PigStorage(',') AS (id:int,name:chararray,sex:chararray,age:int,address:chararray) ;   

  39.   

  40.   

  41. --------pig函数1测试-----------------   

  42.   

  43. --定义按名字分组   

  44. --bb = group_and_count(a,name,1);   

  45. --定义按性别分组   

  46. --cc = group_and_count(a,sex,1);   

  47. --dump bb;   

  48. --dump cc;   

  49.   

  50. -------pig函数2测试------------------   

  51.   

  52. --按年龄降序   

  53. --my_order(a,age,'desc','/tmp/dongliang/318/z');   

  54.   

  55.   

  56.   

  57. --dump a;   

  58.   

  59.   

  60. -------pig函数3测试------------------   

  61.   

  62.  --过滤年龄大于20的,并按性别,分组统计数量   

  63.  r =  myfilter(a,'age',20);   

  64.   

  65.   

  66. dump r;  

--定义pig函数1 支持分组统计数量
DEFINE group_and_count (A,group_key,number_reduces) RETURNS B {
 
 d = group $A by $group_key parallel $number_reduces;
 
 $B = foreach d generate group, COUNT($1);

};


--定义pig函数2 支持排序
--A 关系引用标量
--order_field 排序的字段
--order_type 排序方式 desc ? asc ?
--storedir 存储的HDFS路径
--空返回值
define my_order(A,order_field,order_type,storedir) returns void {
 
  d = order $A by $order_field $order_type ;
  store  d into '$storedir' ;  
 

}; 


--定义pig函数3,支持filter过滤,以及宏命令里面调用

--定义过滤操做
define  myfilter (A,field,count) returns B{

   b= filter $A by $field > $count ;

   $B = group_and_count(b,'sex',1);

};


a = load  '/tmp/dongliang/318/person' using PigStorage(',') AS (id:int,name:chararray,sex:chararray,age:int,address:chararray) ;


--------pig函数1测试-----------------

--定义按名字分组
--bb = group_and_count(a,name,1);
--定义按性别分组
--cc = group_and_count(a,sex,1);
--dump bb;
--dump cc;

-------pig函数2测试------------------

--按年龄降序
--my_order(a,age,'desc','/tmp/dongliang/318/z');



--dump a;


-------pig函数3测试------------------

 --过滤年龄大于20的,并按性别,分组统计数量
 r =  myfilter(a,'age',20);


dump r;



在上面的脚本中,散仙定义了三个函数,
(1)分组统计数量
(2)自定义输出存储
(3)自定义过滤并结合(1)统计数量

经过这3个例子,让你们对pig函数有一个初步的认识,上面的函数和代码都在一个脚本中,这样看起来不太友好,并且重用性,尚未获得最大发挥,实际上函数和主体脚本是能够分离的,再用的时候,咱们只须要导入函数脚本,便可拥有全部的函数功能,这样一来,函数脚本被分离到主脚本外面,就大大增长了函数脚本的重用性,咱们也能够再其余脚本中引用,并且函数脚本中也能够再次引用其余的函数脚本,但前提是不可以,递归引用,这样Pig语法在执行时,是会报错的,下面看下分离后的脚本文件:

一:函数脚本文件

Java代码 复制代码 收藏代码spinner.gif

  1. --定义pig函数1 支持分组统计数量   

  2. --A 关系引用标量   

  3. --group_key 分组字段   

  4. --使用reduce的个数   

  5. --返回最终的引用结果   

  6. DEFINE group_and_count (A,group_key,number_reduces) RETURNS B {   

  7.     

  8.  d = group $A by $group_key parallel $number_reduces;   

  9.     

  10.  $B = foreach d generate group, COUNT($1);   

  11.   

  12. };   

  13.   

  14.   

  15. --定义pig函数2 支持排序   

  16. --A 关系引用标量   

  17. --order_field 排序的字段   

  18. --order_type 排序方式 desc ? asc ?   

  19. --storedir 存储的HDFS路径   

  20. --空返回值   

  21. define my_order(A,order_field,order_type,storedir) returns void {   

  22.     

  23.   d = order $A by $order_field $order_type ;   

  24.   store  d into '$storedir' ;     

  25.     

  26.   

  27. };    

  28.   

  29.   

  30. --定义pig函数3,支持filter过滤,以及宏命令里面调用   

  31. --A 关系引用标量   

  32. --field 过滤的字段   

  33. --count 阈值   

  34. --返回最终的引用结果   

  35.   

  36. define  myfilter (A,field,count) returns B{   

  37.   

  38.    b= filter $A by $field > $count ;   

  39.   

  40.    $B = group_and_count(b,'sex',1);   

  41.   

  42. };   

  43.   

  44.   

  45.   

  46. [search@dnode1 pigmacros]$   

--定义pig函数1 支持分组统计数量
--A 关系引用标量
--group_key 分组字段
--使用reduce的个数
--返回最终的引用结果
DEFINE group_and_count (A,group_key,number_reduces) RETURNS B {
 
 d = group $A by $group_key parallel $number_reduces;
 
 $B = foreach d generate group, COUNT($1);

};


--定义pig函数2 支持排序
--A 关系引用标量
--order_field 排序的字段
--order_type 排序方式 desc ? asc ?
--storedir 存储的HDFS路径
--空返回值
define my_order(A,order_field,order_type,storedir) returns void {
 
  d = order $A by $order_field $order_type ;
  store  d into '$storedir' ;  
 

}; 


--定义pig函数3,支持filter过滤,以及宏命令里面调用
--A 关系引用标量
--field 过滤的字段
--count 阈值
--返回最终的引用结果

define  myfilter (A,field,count) returns B{

   b= filter $A by $field > $count ;

   $B = group_and_count(b,'sex',1);

};



[search@dnode1 pigmacros]$



二,主体脚本文件

Java代码 复制代码 收藏代码spinner.gif

  1. --导入pig公用的函数库   

  2.   

  3. import 'function.pig' ;   

  4.   

  5. a = load  '/tmp/dongliang/318/person' using PigStorage(',') AS (id:int,name:chararray,sex:chararray,age:int,address:chararray) ;   

  6.   

  7.   

  8. --------pig函数1测试-----------------   

  9.   

  10. --定义按名字分组   

  11. --bb = group_and_count(a,name,1);   

  12. --定义按性别分组   

  13. --cc = group_and_count(a,sex,1);   

  14. --dump bb;   

  15. --dump cc;   

  16.   

  17.   

  18. -------pig函数2测试------------------   

  19.   

  20. --按年龄降序   

  21. --my_order(a,age,'desc','/tmp/dongliang/318/z');   

  22. --dump a;   

  23.   

  24.   

  25. -------pig函数3测试------------------   

  26.   

  27.  --过滤年龄大于20的,并按性别,分组统计数量   

  28.  r =  myfilter(a,'age',20);   

  29.  dump r;  

--导入pig公用的函数库

import 'function.pig' ;

a = load  '/tmp/dongliang/318/person' using PigStorage(',') AS (id:int,name:chararray,sex:chararray,age:int,address:chararray) ;


--------pig函数1测试-----------------

--定义按名字分组
--bb = group_and_count(a,name,1);
--定义按性别分组
--cc = group_and_count(a,sex,1);
--dump bb;
--dump cc;


-------pig函数2测试------------------

--按年龄降序
--my_order(a,age,'desc','/tmp/dongliang/318/z');
--dump a;


-------pig函数3测试------------------

 --过滤年龄大于20的,并按性别,分组统计数量
 r =  myfilter(a,'age',20);
 dump r;


须要注意的是,导入的函数文件,须要用单引号引发来,这样咱们就完成了pig函数的重用,是否是很是相似shell的语法呢?有兴趣的同窗们,赶忙体验一把吧!  

相关文章
相关标签/搜索