原創不易,轉載請務必註明,原創地址,謝謝配合!
node
http://my.oschina.net/u/1027043/blog
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集成分詞器來統計新聞詞頻?
在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)
下面看幾個例子,讓咱們迅速對它熟悉並掌握,先看下咱們的測試數據:
linux
1,張三,男,23,中國 web
2,張三,女,32,法國 shell
3,小花,男,20,英國 數據庫
4,小紅,男,16,中國 編程
5,小紅,女,25,洛陽 服務器
6,李靜,女,25,中國河南安陽 函數
7,王強,男,11,英國 oop
8,張飛,男,20,美國 學習
再看下pig腳本:
--定義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語法在執行時,是會報錯的,下面看下分離後的腳本文件:
一:函數腳本文件
--定義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]$
二,主體腳本文件
--導入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的語法呢?有興趣的同窗們,趕忙體驗一把吧!