Pig數據Type, Order,Limit關係操做

Pig的數據模型基本分爲2大類,基本類型,和複雜類型。基本類型只能包含一個簡單的數值,複雜類型能夠包含其餘全部類型。java

基本類型,和其餘大多數主流語言提供的簡單類型同樣,Pig也提供int, long, float, double,chararray(Sring),bytearray(字節類型)程序員

Pig是用Java開發的,所以Java程序員應該能想象的到,上面的基本類型都是java.lang包中對應類型的實現的。ide

須要注意的是,Pig的基本類型中沒有Boolean值,可是在Pig的運行期倒是有Boolean值的,由於關係Filter須要一個Boolean關係爲true時數據才能流過去。這點上須要注意。oop

複雜類型包括Map, Tuple和Bagurl

Map至關於Java的Map<String, Object>類型的。Key必須是一個chararray,而值能夠是任何基本和複雜類型。表示爲[key#value]spa

Tuple能夠理解爲Java中的List,其實若是懂得Python,它更像Python中的Tuple[元組],表示爲:(1, 「abc」, 1.5)等.net

Bag的數據類型按個人理解爲Java的Set<Tuple>,它內部的數據是無序的。表示爲:{(1, 「abc」, 1.5),(2, 「bcd」, 2.0)...}code

緊接着上一篇統計單詞的例子,下面我作一些改寫。一步一步的講解Pig的運行數據狀態。blog

統計單詞的第一步就是要把文本文件讀入,而後分詞。排序

1 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的結果。

1 dump words;
輸出的結果:
1 (extravagant,)
2 (without)
3 (imagine)
4 (in)
5 (that)
6 (unfathomable)
7 (BECAUSE)
8 (self-tyranny--Nature)
我截取了一段結果,能夠看到他們的數據都是Tuple,裏邊只有一個值。

所以若是爲了統計詞頻,下一步應該是用Mapreduce的Map把相同的詞彙集到一塊兒,而後統計。下面的這句代碼就很輕鬆的實現。

1 grpd = group words by line;
緊接着,咱們輸出grpd(dump grpd;)的結果查看。
1 (different,{(different),(different)})
2 (extremely,{(extremely)})
3 (mistaken,,{(mistaken,)})
4 (naturally,{(naturally)})
5 (ourselves,{(ourselves),(ourselves)})
6 (permitted,{(permitted)})
7 (something,{(something),(something)})
熟悉MapReduce應該很清楚了,他把相同的詞合併到了一塊兒,組成了一個Tuple(word, {word, word})的數據格式。Reduce再把 {word, word }遍歷一邊得出一個count就實現了統計詞頻的效果了。

完整的程序:

1 words = load 'nie.txt'using PigStorage(' ') as (line); --以空格做爲分隔符把內容分詞讀入
2 grpd = group words by line;     --以每一個單詞聚類,真實的是一個MapReduce的Map階段
3 cntd = foreach grpd generate group, COUNT(words); -- 這裏既上一步Map完成緊接着Reduce階段進行統計
4 dump grpd;  --直接在終端打印結果便於查看
上面的程序正常運行下來應該能統計出詞了該詞出現的次數,文本很長的狀況下着實沒有什麼意思,通常都會看前面高頻的一些詞彙,所以還應該作個Order By,而後取出前面的數據。幸虧Pig是支持的。
1 cous = order cntd by $1 desc;
2 limitresult = limit cous 50;
3 dump limitresult;

接着上面的dump前,繼續排序,而後截取前面50條結果。

應該能看到,程序中使用了一個$1的的變量,由於foreach總會建立一個Tuple,而在COUNT()沒有特別的指出別名,所以應該是匿名的,匿名的變量能夠用$取出值,下標老是從0開始。Pig Latin是能夠用as 強調別名的,這和SQL的AS是同樣的。

運行該程序用的時間明顯長了不少。運行結果如:

01 (the,32)
02 (and,29)
03 (of,21)
04 (that,12)
05 (in,12)
06 (to,11)
07 (is,10)
08 (it,9)
09 (a,9)
10 (as,7)
11 (for,6)
12 (you,5)
13 (will,4)
14 (The,4)
15 (value,3)
16 (which,3)
如今的結果明顯有意義了不少。我在第一次運行這個程序的時候,還拋出了OutofMemory的異常,所以還更改了Pig的配置文件。PigHome/conf/pig.properties.在後邊增長這樣的配置:

1 pig.cachedbag.memusage=0
2 io.sort.mb=40
3 io.sort.record.percent=0.1
Pig排序時須要很大的內存,經過參數能夠把部分數據臨時序列化到硬盤,具體的意義能夠上Google搜。

之前玩Hadoop的朋友,是否是以爲Pig能簡化一些Mapreduce的開發呢?

相關文章
相關標籤/搜索