原創不易,轉載請務必註明,原創地址,謝謝配合!
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集成分詞器來統計新聞詞頻?
在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,中國 linux
2,張三,女,32,法國 shell
3,小花,男,20,英國 數據庫
4,小紅,男,16,中國 編程
5,小紅,女,25,洛陽 服務器
6,李靜,女,25,中國河南安陽 ide
7,王強,男,11,英國 函數
8,張飛,男,20,美國 oop
1,張三,男,23,中國 2,張三,女,32,法國 3,小花,男,20,英國 4,小紅,男,16,中國 5,小紅,女,25,洛陽 6,李靜,女,25,中國河南安陽 7,王強,男,11,英國 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;
--定義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函數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公用的函數庫 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的語法呢?有興趣的同窗們,趕忙體驗一把吧!