上一篇博客主要講解了Pig的安裝和一個試手的例子,下面說一下Pig的數據模型。 java
Pig的數據模型基本分爲2大類,基本類型,和複雜類型。基本類型只能包含一個簡單的數值,複雜類型能夠包含其餘全部類型。 程序員
基本類型,和其餘大多數主流語言提供的簡單類型同樣,Pig也提供int, long, float, double,chararray(Sring),bytearray(字節類型) shell
Pig是用Java開發的,所以Java程序員應該能想象的到,上面的基本類型都是java.lang包中對應類型的實現的。 oop
須要注意的是,Pig的基本類型中沒有Boolean值,可是在Pig的運行期倒是有Boolean值的,由於關係Filter須要一個Boolean關係爲true時數據才能流過去。這點上須要注意。 spa
複雜類型包括Map, Tuple和Bag code
Map至關於Java的Map<String, Object>類型的。Key必須是一個chararray,而值能夠是任何基本和複雜類型。表示爲[key#value] 排序
Tuple能夠理解爲Java中的List,其實若是懂得Python,它更像Python中的Tuple[元組],表示爲:(1, 「abc」, 1.5)等 內存
Bag的數據類型按個人理解爲Java的Set<Tuple>,它內部的數據是無序的。表示爲:{(1, 「abc」, 1.5),(2, 「bcd」, 2.0)...} 開發
緊接着上一篇統計單詞的例子,下面我作一些改寫。一步一步的講解Pig的運行數據狀態。 rem
統計單詞的第一步就是要把文本文件讀入,而後分詞。
words = load 'nie.txt' using PigStorage(' ') as (line);加載數據統一用load, 使用了PigStorage加載文件,Pig Storage默認是使用Tab分割文件中的內容的,由於個人例子是一片英文文章,所以只須要用空格作爲分隔符就好 了。as (line)是在爲數據指定模式,全部的數據加載進Pig都是Tuple類型的,所以使用(line),或者(line:chararray)。Tuple也能夠指定多個值的,如(line:chararray,num1:int, num2:double),多個值的Tuple必需要數據要能轉換成這樣的,不然就會出錯,或者加載了其餘不對應的值也是空值,這樣也沒有意義。
Pig Latin腳本的任何地方均可以輸出結果查看,咱們先看一下words的結果。
dump words;輸出的結果:
(extravagant,) (without) (imagine) (in) (that) (unfathomable) (BECAUSE) (self-tyranny--Nature)我截取了一段結果,能夠看到他們的數據都是Tuple,裏邊只有一個值。
所以若是爲了統計詞頻,下一步應該是用Mapreduce的Map把相同的詞彙集到一塊兒,而後統計。下面的這句代碼就很輕鬆的實現。
grpd = group words by line;緊接着,咱們輸出grpd(dump grpd;)的結果查看。
(different,{(different),(different)}) (extremely,{(extremely)}) (mistaken,,{(mistaken,)}) (naturally,{(naturally)}) (ourselves,{(ourselves),(ourselves)}) (permitted,{(permitted)}) (something,{(something),(something)})熟悉MapReduce應該很清楚了,他把相同的詞合併到了一塊兒,組成了一個Tuple(word, {word, word})的數據格式。Reduce再把 {word, word }遍歷一邊得出一個count就實現了統計詞頻的效果了。
完整的程序:
words = load 'nie.txt' using PigStorage(' ') as (line); --以空格做爲分隔符把內容分詞讀入 grpd = group words by line; --以每一個單詞聚類,真實的是一個MapReduce的Map階段 cntd = foreach grpd generate group, COUNT(words); -- 這裏既上一步Map完成緊接着Reduce階段進行統計 dump grpd; --直接在終端打印結果便於查看上面的程序正常運行下來應該能統計出詞了該詞出現的次數,文本很長的狀況下着實沒有什麼意思,通常都會看前面高頻的一些詞彙,所以還應該作個Order By,而後取出前面的數據。幸虧Pig是支持的。
cous = order cntd by $1 desc; limitresult = limit cous 50; dump limitresult;
接着上面的dump前,繼續排序,而後截取前面50條結果。
應該能看到,程序中使用了一個$1的的變量,由於foreach總會建立一個Tuple,而在COUNT()沒有特別的指出別名,所以應該是匿名的,匿名的變量能夠用$取出值,下標老是從0開始。Pig Latin是能夠用as 強調別名的,這和SQL的AS是同樣的。
運行該程序用的時間明顯長了不少。運行結果如:
(the,32) (and,29) (of,21) (that,12) (in,12) (to,11) (is,10) (it,9) (a,9) (as,7) (for,6) (you,5) (will,4) (The,4) (value,3) (which,3)如今的結果明顯有意義了不少。我在第一次運行這個程序的時候,還拋出了OutofMemory的異常,所以還更改了Pig的配置文件。PigHome/conf/pig.properties.在後邊增長這樣的配置:
pig.cachedbag.memusage=0 io.sort.mb=40 io.sort.record.percent=0.1Pig排序時須要很大的內存,經過參數能夠把部分數據臨時序列化到硬盤,具體的意義能夠上Google搜。
之前玩Hadoop的朋友,是否是以爲Pig能簡化一些Mapreduce的開發呢?