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

已总结Pig系列的学习文档,点击末尾处,阅读原文即可查看所有,希望对大家有用,感谢关注! 在Hadoop的生态系统中,如果我们要离线的分析海量的数据,大多数人都会选择Apache Hive或Apache Pig,在国内总体来说,Hive使用的人群占比比较高, 而Pig使用的人相对来说,则少的多,这并不是因为Pig不成熟,不稳定,而是因为Hive提供了类数据库SQL的查询语句,使得大多人上手Hive非常容易,相反而Pig则提供了类Linux shell的脚本语法,这使得大多数人不喜欢使用。 如果在编程界,统计一下会SQL和会shell,那个人数占的比重大,散仙觉得,毫无疑问肯定是SQL语句了。因为有相当一部分编程人员是不使用Linux的,而是微软的的一套从C#,到ASP.NET,SQL Server再到Windows的专用服务器 。 OK,扯远了,赶紧回来,使用shell的攻城师们,我觉得都会爱上它的,因为在linux系统中,没有比shell更简洁易用了,如果再配上awk和sed更是如虎添翼了。 我们都知道shell是支持函数调用的,这一点和JavaScript是非常类似的,通过定义函数我们可以重复使用某个功能,而不用再次大量编码,其中,把变的东西,分离成参数,不变的东西定义成语句,这样以来,就能够降低编码的冗余和复杂性,试想一下,如果Java里,没有方法,那将会是多么不可思议的一件事。 Pig作为类shell的语言,也支持了函数的方式,封装某个功能,以便于我们重用,这一点相比Hive来说,是一个很好的优势。 下面先看下定义Pig函数(也叫宏命令)定义的语法: DEFINE (macros) : 支持的参数: alias pig的标量引用 整形(integer) 浮点型(float) 字符串(String) 下面看几个例子,让我们迅速对它熟悉并掌握,先看下我们的测试数据:

Java代码

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


再看下pig脚本: 

Java代码

--定义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代码

--定义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代码

--导入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的语法呢?有兴趣的同学们,赶紧体验一把吧!

原文发布于微信公众号 - 我是攻城师(woshigcs)

原文发表时间:2015-03-20

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏walterlv - 吕毅的博客

使用 ExceptionDispatchInfo 捕捉并重新抛出异常

发布于 2017-10-23 14:22 更新于 2017-10...

871
来自专栏编程

养良好C语言编程风格,编优质C语言代码,这才是C语言的开始

个人c语言编程风格总结 总结一下我个人的编程风格及这样做的原因吧,其实是为了给实验室写一个统一的C语言编程规范才写的。首先声明,我下面提到的编程规范,是自己给自...

4665
来自专栏喔家ArchiSelf

一个函数的自白

我是——编程世界的函数,不是数学中的幂,指,对和三角函数等等,但是和f(x)又有着千丝万缕的关系。

1295
来自专栏编程

PLC编程优化方法,让程序运行提速!

PLC、DCS、仪器仪表、电气技术资料,一网打尽 通过本方法优化可以极大的减少程序语句数,使PLC程序更简洁、可读性更好,由于不需要做耗时的类型转换,程序运行效...

2149
来自专栏V站

php时间函数 time()和Date()详解

使用函式 date() 实现  <?php echo $showtime=date("Y-m-d H:i:s");?>  显示的格式: 年-月-日 小时:分...

7286
来自专栏WindCoder

Java设计模式学习笔记—桥接模式

文章最后“Java设计模式笔记示例代码整合”为本系列代码整合,所有代码均为个人手打并运行测试,不定期更新。本节内容位于其Bridge包(package)中。

881
来自专栏互扯程序

设计模式不止23种!

现在是资源共享的时代,同样也是知识分享的时代,如果你觉得本文能学到知识,请把知识与别人分享。

1234
来自专栏腾讯Bugly的专栏

如何定位Obj-C野指针随机Crash(三):如何让Crash自报家门

本文主要介绍如何利用OC Runtime的特性,让OC野指针对象主动抛出自己的信息,秒杀某些全系统栈Crash。 ? 陈其锋,腾讯SNG即通产品部音视频技术中心...

7464
来自专栏听雨堂

Python中Json解析的坑

JSON虽好,一点点不对,能把人折腾死: 1、变量必须要用双引号 2、如果是字符串,必须要用引号包起来 Error:Expecting : delimiter:...

2509
来自专栏听雨堂

字符串处理总结(旧)

在各类应用软件的开发中,字符串操作是最常见的操作之一。在各种不同的数据类型中,字符串类型是和现实世界关联最紧密的。对字符串的读入、比较、拼接、搜索、匹配、替换、...

2488

扫码关注云+社区

领取腾讯云代金券