2016年6月19日 星期日

中古車交戰守則

中古車交戰守則

目錄

合約

購車時絕對要簽合約 , 合約的內容必須要特別著名以下這幾點:

  1. 本車非泡水車且引擎與變速箱等等重要機械零件並無進過水
  2. 本車非重大事故車且不曾有任何重大命案事故與本車有關係
  3. 本車前車身(前擋風玻璃以前之位置)並無任何的碰撞且內部車輛的主架構沒有任何維修記錄
  4. 買車時的公里數

賞車

車頭

車頭撞擊

  1. 如果車頭、保險桿、大燈等部分烤漆有細微的點狀或是刮傷且平均分布數量很多 , 就表示前車主開車習慣不佳時常沒有保持安全距離 , 因為前車在行駛時會有跳石就會直接撞擊本車的車頭 , 就要嚴重懷疑是否有車頭撞擊的可能
  2. 左右兩邊頭燈的新舊程度必須看起來一樣
  3. 引擎蓋左右兩側與葉子版的縫隙距離必須一樣

車身

車身撞擊

  1. 葉子版前門後門 之間的縫隙並需一樣就表示無任何碰撞
    enter image description here

後車追撞

  1. 行李箱左右兩側為後葉子版這邊的葉子版無法更換的如果有動過的痕跡就會生鏽 , 所以有這種狀況就不要買這車子了
    enter image description here
  2. 行李箱下層也是有兩個大樑 , 只要撞過絕對是用拉的 , 因為車尾板金不能夠跟換 , 直要摺過在拉絕對會有皺摺
    enter image description here

引擎室

車頭撞擊

  1. 當車頭遭撞擊時水箱架首先遭殃 , 所以水箱架如果撞到的話一定需要左右這個螺絲有更動過來更換水箱架 , 所以如果螺絲跟版件接縫的地方一定會有掉漆的痕跡
  2. 如果撞擊嚴重引擎蓋也需要更換 , 所以固定引擎蓋的螺絲如果有更動就表示有更換過
    enter image description here
  3. 所有車子在引擎室下方都會有左右個一根很大的大梁 , 這個大樑是支撐整個車子很重要的零件 , 如果這個橫樑太過平順太過光華亮亮的 , 就有可能撞得很嚴重引擎都掏起來噴漆過 , 但如果感覺很自然沒有皺摺就是正常沒有撞過 , 並且左右兩隻都要檢查
    enter image description here

內裝

味道

  1. 如果味道是一種非常濃烈的味道就表示可能前車主會在車內抽煙 , 所以為了掩蓋味道而噴很濃的香水

車頭撞擊

  1. 車門打開後 , 門與車子之間的固定位置是否有被換過螺絲等等
    enter image description here

車輛泡水

  1. 在檢查安全帶得時候可以把安全帶拉到底檢查是否有泥沙淤積 , 而且要前後做五具安全帶掉檢查一遍
  2. 車上全部的功能都要正常 , 電動窗必須要非常滑順不能卡卡的或是有怪聲
  3. 發動電門儀表板上面全部的燈都要會亮
  4. 發動車子時不能有異音

車齡

  1. 椅子靠腰的部分如果有很嚴重的磨損就表示車齡比較久了 , 但是如果很乾淨或是很不自然那就表示更慘 , 他在偽裝他的車齡
    enter image description here
    enter image description here

里程數

  1. 國人平均每年的里程數是 1.5萬公里所以只要 年份 X 1.5w 所出來的數字低於現在所使用的里程數就是低里程數

油、水、電

機油

  1. 機油很黑沒有換過表示前任車主沒有好好保養

輪胎

  1. 胎壓
  2. 出場年限

引擎

  1. 啟動引擎時如果震動過大表示引擎腳或是引擎可能沒有保養的很好
  2. 輕踩油門看看有沒有異音或是皮帶的異音
  3. 吹油門時注意排氣管是否有藍色的煙 , 如果有就表示這個引擎吃機油 , 千萬不要買

檔位

  1. 每一個檔位都打打看並且停留的幾秒就可以知道變速箱的某個檔位、齒比、齒輪、離合器有沒有比較耗損

方向盤

  1. 一般手握的地方會磨損的比要嚴重 , 如果整個都很新就可能有換過
  2. 如果里程數很低而方向盤的磨損程度很高就表示里程數造假

顏色

  1. 銀白色的車子要調色比較困難 , 所以如果有部分位置有重新烤漆很好辨識

車身號碼

連結

購車後

買中古車以後需要注意或是需要跟換的部分

煞車系統

  1. 煞車來令片
  2. 煞車碟盤

五油三水

  1. 機油
  2. 變速箱油
  3. 動力方向機油
  4. 煞車油 與 煞車油管
  5. 汽油

  1. 引擎冷卻水、主水箱、副水箱、水管
  2. 電瓶水
  3. 雨刷水

避震

  1. 如果遇到窟㝫車身彈跳一次算是正常、兩次需要注意、三次就需要跟換避震器了

引擎

  1. 聽到清脆的金屬敲擊聲、爆震因立即停車熄火 , 過 5 至 10 分鐘後在發動引擎感覺好像沒電就表示已經小縮缸了
  2. 氣門與活塞的頂部拆開來看到大面積白色表示機油潤滑不足
  3. 引擎冒藍煙表示機油進了燃燒室
  4. 4.

濾芯

  1. 空氣濾清氣
  2. 機油濾芯與油封
  3. 冷氣濾芯
  4. 汽油濾芯

定時檢查是否需要更換

皮帶

  1. 兩年是有龜裂要跟換
  2. 引擎運轉時的異音如果是從皮帶發出來的話就必須更換
  3. 必須檢查 正時皮帶、發電機皮帶、動力方向盤泵浦皮帶、冷氣壓縮機
    enter image description here

2016年6月7日 星期二

Apache Pig 語法教學

Pig 語法教學(StackEdit)

目錄



前言

大家好我是 King 我在寫這篇文章的時是我大一的時候因為要比賽所以才開始學習 Pig , 但是當時在學習 Pig 的時候根本沒有「繁體中文」的教學文 , 因為這個技術實在是太新了所以我只好看原文的官方教學來學習 , 在這裡在建議大家要走資工的朋友們英文很重要而現在我也還在惡補我爛到不行的英文 , 廢話說完了以下兩個是 Pig 官方的教學手冊。

連結 :

入門

PigHDFS

Pig 的系統中所要使用的檔案與處理過後的檔案都是放置在 HDFS 的檔案統當中 , 換句話說就是在開始使用 Pig 之前就必須先把需要的資料上傳至 HDFS 檔案系統中這樣 Pig 才可以把檔案讀取近來歐 , 相反地儲存也是同樣的 Pig 會將檔案儲存在你指定的 HDFS 目錄當中 , 這邊有一個非常的重要的觀念要教大家就是「Pig 在儲存檔案的時候當是以目錄的方式做儲存」

啟動 PigPig 的執行方式

要啟動 Pig 有兩種方式 , 現在來介紹地一種方式「交談式」在這邊你可以像是跟 Pig 對話一般將你要的程式碼一行一行的打進去而且可以覆蓋之前所打的指令 , 在剛開始規劃程式的時候非常的好用可以一直跟改之前所打的程式碼並且可以隨時查看結果 , 但唯一的缺點就是不好查看之前所打的程式碼所以所以必須在邊規劃程式的時候就邊開一個 Notepad++1 把之前打的程式記錄下來在使用第二種方法將他執行

dsa01@cla01:~$ pig
grunt>

第一種「交談式」的方法介紹完了就要來介紹類似腳本的啟動方式了 , 在這邊你必須先用任意一個 Text Edit 新建一個附檔名為 .pig 的檔案 , 然後在檔案裡面把上面「交談式」所打的程式打進去檔案裡面 , 之後每次要執行的時候就只要下達以下指令就可以啟動了 , 在 Linux 下我推薦使用 Emacs2 作為 Text Edit

dsa01@cla01:~$ pig -f [.pig檔案路徑]

接下來就要說說 Pig 的執行方式了 , 但是在這之前有一個觀念要傳授給大家 , 「Pig 是一支 Java 程式然而 Pig 的工作就是在幫你快速有效率的完成一支 Java 的程式來處理你給他的資料」 , 但是一般人認為 Pig 在讀取每一條指令的時候其實背後已經在操作資料了 , 但其實不是 , Pig 中有一條指令是 DUMP 而這條指令的工作其實是非常大的 , 他並不光光只是把結果顯示出來而已 , 就像剛剛說的一樣「Pig」是在幫你寫 Java 程式 , 然而 DUMP 的工作就是把你打的指令通通 撰寫 -> 編譯 -> 執行 -> 顯示 , 所以在下達 DUMO 指令時電腦才會運算的比較久而在一般的指令下達時 Pig 只是在記錄你下了什麼指令而已

認識資料的個部分名稱

A = {1,(2,3),{(4,5),(6,7)}}

上面這一行資料如果要用說的方式來表示是這樣的「A 關連 {1,(2,3),{(4,5),(6,7)}
"1" 沒有任何括號的是一個 字段(Fields) , 而一個 字段(Fields) 也就是一個 數據(Data)
"(2,3)" 被小括號包住的是一個 元組(Tuples) , 而在 元組(Tuples) 裡面可以有若干個 字段(Fields) 或是一個 字段(Fields) ,例如:(1),(1,2),(1,2,3)
"{(4,5),(6,7)}" 被大括號包住的是一個 包(Bags) , 一個 包(Bags) 可以有若干個 元組(Tuples) , 也可以稱為是 元組(Tuples) 的集合

認識 Pig 的資料型態

資料名稱(英) 資料名稱(中) 敘述
普通資料類
int 整數 Signed 32-bit integer
long 長整數 Signed 64-bit integer
float 浮點數 32-bit floating point
double 精確浮點數 64-bit floating point
NULL 空值
陣列類
chararray 字串 Character array (string) in Unicode UTF-8 format
bytearray 位元組陣列 Byte array (blob)
Pig 資料類型
tuple 元組 An ordered set of fields.
bag An collection of tuples.
map 鍵與值 A set of key value pairs.

認識 Pig 的註解

--單行著註解,有效範圍只有在 --(雙減號) 與 Entel(換行) 之前/*多行註解,有效範圍在 /* 與 */ 之間,換行照樣有效*/

文章中會使用的符號

"..." -> 以此類推的意思

文章中會使用的資料

在之後的介紹中會出現許多的舉例 , 所以在這邊就先把以後會用到的原始資料放上來 , 之後久不再刻意 cat 資料了

a.txt

1,2,3
4,5,6

回到目錄


b.txt

1,2,3,6,9,8
1,2,3,5,9,6
5,9,6,3,5,8
5,9,6,2,4,8
3,2,4,8,9,5
3,6,9,8,5,4

回到目錄


c.txt

20150922,017,u016045383
20150821,001,u015769781
20150710,008,u008137791
20150830,018,u014711537
20150627,001,u014616537
20150830,002,u007591963
20150726,038,u014540733
20150715,040,u014792743
20150627,012,u006343463
20150707,018,u005655603
20150911,005,u008969559
20150820,018,u015235929
20150919,040,u003234985
20150602,039,u008469313
20150617,040,u201308777
20150916,021,u002529119

回到目錄


d.txt

Alice,turtle,1
Alice,goldfish,5
Alice,cat,2
Bob,dog,2
Bob,cat,2

回到目錄


e.txt

John,fl,3.9F
John,wt,3.7F
John,sp,4.0F
John,sm,3.8F
Mary,fl,3.8F
Mary,wt,3.9F
Mary,sp,4.0F
Mary,sm,4.0F

回到目錄


f.txt

8,9,0,1,8,9,1,1
2,3,4,5,2,3,4,5
6,7,3,7,2,2,3,7

回到目錄

指令介紹

這裡所介紹的指令是我自己有實際使用過的指令 , 換句話說就是我沒有用過的就不會介紹出來 , 以免我自己不清楚而教了錯誤的指令 , 所以如果我這邊沒有介紹到的就請移駕到 Pig 參考手冊 1Pig 參考手冊 2 尋找你要的答案吧 !

LOAD

語法

簡易型的載入敘述 , 比較不建議使用這種方式載入檔案 , 原因會在範例裡加以說明

代號 = LOAD '[檔案路徑]';

進階型的載入敘述 , 這條敘述不只是載入檔案 , 還包含著「設定分隔符號」與「欄位的代號與資料的型態」

代號 = LOAD '[檔案路徑]' using PigStorage('[分隔符]') AS ([欄位名稱]:[資料型別], [欄位名稱]:[資料型別], ...); 
  • LOAD '[檔案路徑]'

    • 載入資料的時候要使用的敘述 , '[檔案路徑]' 這邊要打上存在 HDFS 的檔案路徑
  • using PigStorage('[分隔符]')

    • 敘述中其中的這一段就是設定要Pig系統在讀取資料的時候要用什麼符號來辨識欄位的分隔 , 舉例來說如果你讀取的是 Excel(.csv) 的檔案在Excel的系統中是使用 , 號來做欄位的分隔 , 所以這邊的程式碼就邀這樣寫using PigStorage(',') , 注意要要依照自己要讀取的檔案來設定分隔符號 , 不要傻傻的都填上 , 這樣你會發現讀取進來的資料全部通通都擠在一個欄位裡面
  • AS ([欄位名稱]:[資料型別], [欄位名稱]:[資料型別], ...)

    • 這裡就是要分別給每一個欄位設定「欄位的名稱」與「資料的型態」,詳細的說明於範例中做加以說明

範例

1 - 1

A = LOAD '/teaching/a.txt';

DUMP A;
(1,2,3)(4,5,6)

DESCRIBE A;
Schema for A unknown.
  • A = LOAD '/teaching/a.txt';
    • 這邊先示範一次使用不建議的方式載入 a.txt 文件
  • DUMP A;
    (1,2,3)
    (4,5,6)
    • DUMP 指令是用來查看目前敘述所操作的出來的資料 , 所以係在看 A 敘述所載入的資料是正常的
  • DESCRIBE A;
    Schema for A unknown.
    • DESCRIBE 指令是用來查看目前敘述所操作的出來的資料結構 , 而當我們下達這指令時系統回復我們 Schema for A unknown. 翻譯成中文意思是 A 的資料結構不明 , 所以這樣就知道為什麼不建議使用簡易的方式載入資料 , 雖然在之後還會交到如何重新設定資料類型 , 但還是建議大家在載入的時候就做好設定

1 - 2

A = LOAD '/teaching/a.txt' using PigStorage(',') AS (a:int, b:int, c:int);

DUMP A;
(1,2,3)(4,5,6)

DESCRIBE A;
A: {a: int,b: int,c: int}
  • A = LOAD '/teaching/a.txt' using PigStorage(',') AS (a:int, b:int, c:int);
    • 接下來就是要使用推薦的方式載入 a.txt 文件 , 在本次範例中就可以看出實際的差別了
  • DUMP A;
    (1,2,3)
    (4,5,6)
    • 這裡在顯示的時候跟上一個範例是一樣的
  • DESCRIBE A;
    A: {a: int,b: int,c: int}
    • 實際的差別就會差別這邊顯示出來接下來就要來說明一下得到的這個資料結構的意思吧 , A: 表示是這個 A 敘述所處理過的資料結構 , 在 {a: int,b: int,c: int} 中的 a, b, c 都是欄位名稱的意思 , 在第一筆資料內 a 指的是 1b 指的是 2c 指的 3 , 而 int 指的就是資料的型態了 !

DUMP

將下達的指令 撰寫 -> 編譯 -> 執行 -> 顯示 , 如果你看不懂這句話的話就表示你沒有看 啟動 PigPig 的執行方式 或是忘記了 , 所以還不趕快回去複習裡面的觀念可是很重要的 !!! 但是不要以為 DUMP 永遠指能放在程式的最後面歐 , 也不要以為他在程式裡面指能出現一次歐 , 如果你需要看很多條敘述所操作出來的指令你可以在一份程式你呼叫 DUMP 無限次 , 而唯一需要遵守的規則指有兩條 1. 必須擺在你要看的敘述的後面2. 必須是存在的 [代號]

語法

DUMP [代號];

範例

2 - 1

A1 = LOAD '/teaching/a.txt';

DUMP A1;
(1,2,3)(4,5,6)

A2 = LOAD '/teaching/b.txt';

DUMP A2;
(1,2,3,6,9,8)
(1,2,3,5,9,6)
(5,9,6,3,5,8)
(5,9,6,2,4,8)
(3,2,4,8,9,5)
(3,6,9,8,5,4)
  • A1 = LOAD '/teaching/a.txt';
    • 只是要測試 DUMP 所以用簡易的方式載入 a.txt
  • DUMP A1;
    (1,2,3)
    (4,5,6)
    • 將像剛剛說的一樣只要在你要看的敘述後面就可以放 DUMP 來檢視你要看的資料
  • A2 = LOAD '/teaching/b.txt';
    • 只是要測試 DUMP 所以用簡易的方式載入 b.txt
  • DUMP A2;
    (1,2,3,6,9,8)
    (1,2,3,5,9,6)
    (5,9,6,3,5,8)
    (5,9,6,2,4,8)
    (3,2,4,8,9,5)
    (3,6,9,8,5,4)
    • DUMP 可以放在敘述下的任意位置 , 也可以在程式中放置任意多的 DUMP

DESCRIBE

在上面幾個範例中都有使用到的資料結構檢視指令 , 我自己在寫程式的時候都會把 DUMPDESCRIBE 一起使用

語法

DESCRIBE [代號];

範例

3 - 1

A = LOAD '/teaching/a.txt' using PigStorage(',') AS (a:int, b:int, c:int);

DUMP A;
(1,2,3)
(4,5,6)

DESCRIBE A;
A: {a: int,b: int,c: int}
  • DUMP A;
    (1,2,3)
    (4,5,6)

    DESCRIBE A;
    A: {a: int,b: int,c: int}

    • 一起服用(?

FOREACH

對資料中的每一筆做操作 , 可以做 增加欄位刪除欄位資料型態轉換欄位命名欄位運算 還有很多很多…

語法

[代號] = FOREACH [代號] GENERATE [欄位], [欄位], [欄位], ...;

範例

4 - 1

A = LOAD '/teaching/a.txt' using PigStorage(',') AS (a:int, b:int, c:int);

B = FOREACH A GENERATE a, b;

DUMP B;
(1,2)(4,5)

DESCRIBE B;
B: {a: int,b: int}

C = FOREACH A GENERATE a, b, c, 999;

DUMP C;
(1,2,3,999)
(4,5,6,999)

DESCRIBE C;
C: {a: int,b: int,c: int,int}

D = FOREACH A GENERATE a, b, 999, c;

DUMP D;
(1,2,999,3)
(4,5,999,6)

DESCRIBE D;
D: {a: int,b: int,int,c: int}

E = FOREACH A GENERATE a, b, (double)999, c;

DUMP E;
(1,2,999.0,3)
(4,5,999.0,6)

DESCRIBE E;
E: {a: int,b: int,double,c: int}

F = FOREACH A GENERATE a, b, '999', c;

DUMP F;
(1,2,999,3)
(4,5,999,6)

DESCRIBE F;
F: {a: int,b: int,chararray,c: int}
  • B = FOREACH A GENERATE a, b;
    • 這邊的敘述指留下 ab 的欄位
  • DUMP B;
    (1,2)
    (4,5)
    • DUMP 後的資料已經成功去除 C 欄位的資料了
  • DESCRIBE B;
    B: {a: int,b: int}
    • 資料結構中也可以看的出來
  • C = FOREACH A GENERATE a, b, c, 999;
    • 這條敘述的操作是要在每一筆資料的最後增加一個欄位並且在欄位裡填上 999
  • DUMP C;
    (1,2,3,999)
    (4,5,6,999)
    • 這邊就顯示出來剛剛增加的欄位與 999 是成功的
  • DESCRIBE C;
    C: {a: int,b: int,c: int,int}
    • 在觀看資料結構的時候就可以發現剛剛增加的 999 欄位被 Pig 預設為 int 的資料型態 , 如果增加欄位資料是 999.0 就會變成 duoblelong
  • D = FOREACH A GENERATE a, b, 999, c;
    • 這邊要說明的是要增加的欄位加在那邊都可以不一定要加在最後面 , 當然如果你把最後一個 c 去掉變成 D = FOREACH A GENERATE a, b, 999; 就會發現 c 欄位不會顯示了!
  • DUMP D;
    (1,2,999,3)
    (4,5,999,6)
    • 欄位也可以亂插 (?
  • DESCRIBE D;
    D: {a: int,b: int,int,c: int}
    • 預設的資料結構一樣也是 int
  • E = FOREACH A GENERATE a, b, (double)999, c;
    • 如果你在加入欄位的時候沒有指定資料型態 Pig 對數字的預設是 int , 相對的你也可以自訂所以我就在 999 前面加一個 (double) 就可以一便設定資料型態
  • DUMP E;
    (1,2,999.0,3)
    (4,5,999.0,6
    • 因為上一條敘述所加入的 999double 的資料型態 , 而 double精確浮點數 的意思所以會顯示有小數點的 999.0
  • DESCRIBE E;
    E: {a: int,b: int,double,c: int}
    • 這邊證實了我們設定的 double 是正常的
  • F = FOREACH A GENERATE a, b, '999', c;
    • 有沒有發現這邊的 999 前後加了 ' 號 , 所以這邊的 999 已經不是個 int 了他是一個 chararray(字串) , 不管任何資料只要加了 ' 號在前後就表示這是 chararray(字串) 資料 , 而即便 chararray(字串) 資料內的資料是數字也不能用於 計算 的函式 , 如果需要 計算 就要用到之後教的 資料轉型
  • DUMP F;
    (1,2,999,3)
    (4,5,999,6)
    • 看起來還是數字?不要被騙了!
  • DESCRIBE F;
    F: {a: int,b: int,chararray,c: int}
    • 真相只有一個(? 他就是 chararray(字串)

4 - 2

A = LOAD '/teaching/a.txt' using PigStorage(',') AS (a:int, b:int, c:int);

B = FOREACH A GENERATE (chararray)a, (double)b, c;

DUMP B;
(1,2.0,3)
(4,5.0,6)

DESCRIBE B;
B: {a: chararray,b: double,c: int}

C = FOREACH A GENERATE '11ASD';

D = FOREACH C GENERATE (int)$0;

DUMP D;
()()

DESCRIBE D;
D: {int}
  • B = FOREACH A GENERATE (chararray)a, (double)b, c;
    • 只要在欄位名稱前加入你要轉型的資料名稱就可以轉型
  • DUMP B;
    (1,2.0,3)
    (4,5.0,6)

    DESCRIBE B;
    B: {a: chararray,b: double,c: int}

    • 成功轉型結果
  • C = FOREACH A GENERATE '11ASD';
    • 這邊把全部的欄位都刪除並且增加欄位資料 11ASD
  • D = FOREACH C GENERATE (int)$0;
    • 因為將全部的欄位都刪除後新增加的欄位並沒有重新命名所以用 $0 表示
  • DUMP D;
    ()
    ()
    • 資料轉換失敗因為如果要把 chararray 轉成 int 就必須全部都是 數字 才會成功 !
  • DESCRIBE D;
    D: {int}
    • 雖然資料顯示不出來但是欄位的屬性來是不變的

4 - 3

A = LOAD '/teaching/a.txt' using PigStorage(',') AS (a:int, b:int, c:int);

B = FOREACH A GENERATE a AS x, b AS y, c AS z;

DUMP B;
(1,2,3)
(4,5,6)

DESCRIBE B;
B: {x: int,y: int,z: int}
  • B = FOREACH A GENERATE a AS x, b AS y, c AS z;
    • 這邊要展示的是 重新命名 的方法
  • DUMP B;
    (1,2,3)
    (4,5,6)
    • 重新命名不會跟改到資料本生
  • DESCRIBE B;
    B: {x: int,y: int,z: int}
    • a、b、c 改成 x、y、z

4 - 4

A = LOAD '/teaching/a.txt' using PigStorage(',') AS (a:int, b:int, c:int);

B = FOREACH A GENERATE a+b+c AS sum:int;

DUMP B;
(6)
(15)

DESCRIBE B;
B: {sum: int}

C = FOREACH A GENERATE (a, b, c) AS data, a+b+c AS sum:chararray;

DUMP C;
((1,2,3),6)
((4,5,6),15)

DESCRIBE C;
C: {data: (a: int,b: int,c: int),sum: chararray}
  • B = FOREACH A GENERATE a+b+c AS sum:int;
    • 將全部的欄位的值加起來並且命名為 sum 設定資料型態為 int , 是不是覺得 sum:int 很熟悉呢?其實就跟 LOAD 是一樣的設定方式
  • DUMP B;
    (6)
    (15)
    • 這裡所顯示的是 a+b+c
  • DESCRIBE B;
    B: {sum: int}
    • 資料的結構符合設定的規則
  • C = FOREACH A GENERATE (a, b, c) AS data, a+b+c AS sum:chararray;
    • 這邊我們把 a、b、c 欄位包成一個 元組(Tuples) 並且將這個新的欄位命名為 data , 而第二欄位就跟上面的敘述一樣把它們加起來
  • DUMP C;
    ((1,2,3),6)
    ((4,5,6),15)
    • $0元組(Tuples) 是原本的資料 , $1 則是總合
  • DESCRIBE C;
    C: {data: (a: int,b: int,c: int),sum: chararray}
    • 元組(Tuples) 命名為 data $1 命名為 sum 資料型態為 chararray

4 - 5

A = LOAD '/teaching/a.txt' using PigStorage(',') AS (a:int, b:int, c:int);

B = FOREACH A GENERATE *;

DUMP B;
(1,2,3)
(4,5,6)

DESCRIBE B;
B: {a: int,b: int,c: int}
  • B = FOREACH A GENERATE *;
    • 說實在我也不知道為什麼要做這個功能 , 因為有沒有這個敘述其實沒有差別 , 他會原封不動把資料掃過一變
  • DUMP B;
    (1,2,3)
    (4,5,6)
    • 看的出來什麼都沒有動
  • DESCRIBE B;
    B: {a: int,b: int,c: int}
    • 這邊也一樣

FILTER

可以使用 正規表示式 或是一般的 表達式 作過濾

語法

一般的 表達式 使用的敘述

[代號] = FILTER [代號] BY ([表達式]);

一般的 正規表示式 使用的敘述

[代號] = FILTER [代號] BY [欄位] MATCHES '[正規表示式`]';

兩個 表達式 的敘述

[代號] = FILTER [代號] BY ([表達式]) OR ([表達式]);

與上一個敘述不一樣的地方是在於第二個表達式的地方多了 NOT , 而 NOT 就表示要不等於這個 表達式

[代號] = FILTER [代號] BY ([表達式]) OR (NOT ([表達式]));

範例

5 - 1

A = LOAD '/teaching/b.txt' using PigStorage(',') AS (a:int, b:int, c:int, d:int, e:int, f:int);

B = FILTER A BY (d == 8);

DUMP B;
(3,2,4,8,9,5)
(3,6,9,8,5,4)

DESCRIBE B;
B: {a: int,b: int,c: int,d: int,e: int,f: int}

C = FILTER A BY (d > 4);

DUMP C;
(1,2,3,6,9,8)
(1,2,3,5,9,6)
(3,2,4,8,9,5)
(3,6,9,8,5,4)

DESCRIBE C;
C: {a: int,b: int,c: int,d: int,e: int,f: int}

D = FILTER A BY (e < 5);

DUMP D;
(5,9,6,2,4,8)

DESCRIBE D;
D: {a: int,b: int,c: int,d: int,e: int,f: int}
  • B = FILTER A BY (d == 8);
    • 指留下欄位 b 等於 8 的資料
  • C = FILTER A BY (d > 4);
    • 指留下欄位 b 大於 4 的資料
  • D = FILTER A BY (e < 5);
    • 指留下欄位 e 小於 5 的資料

5 - 2

A = LOAD '/teaching/c.txt' using PigStorage(',') AS (dates:chararray, catid:chararray, userid:chararray);

B = FILTER A BY dates MATCHES '201506.*';

DUMP B;
(20150627,001,u014616537)
(20150627,012,u006343463)
(20150602,039,u008469313)
(20150617,040,u201308777)

DESCRIBE B;
B: {dates: chararray,catid: chararray,userid: chararray}
  • B = FILTER A BY dates MATCHES '201506.*';
    • 使用 正規表示式 來過濾非 '201505.*' 的資料 , 而 .* 裡面的 . 表示「任意的字元」* 表示出現的次數不限至 , 所以兩個加起來就表是 後面不管接什麼通通都可以 !
  • DUMP B;
    (20150627,001,u014616537)
    (20150627,012,u006343463)
    (20150602,039,u008469313)
    (20150617,040,u201308777)
    • 當然的… 留下了這些資料

GROUP

依照指定的 [欄位] 將資料做分類

語法

[代號] = GROUP [代號] BY [欄位];

範例

6 - 1

A = LOAD '/teaching/b.txt' using PigStorage(',') AS (a:int, b:int, c:int, d:int, e:int, f:int);

B = GROUP A BY a;

DUMP B;
(1,{(1,2,3,6,9,8),(1,2,3,5,9,6)})
(3,{(3,2,4,8,9,5),(3,6,9,8,5,4)})
(5,{(5,9,6,3,5,8),(5,9,6,2,4,8)})

DESCRIBE B;
B: {group: int,A: {(a: int,b: int,c: int,d: int,e: int,f: int)}}
  • B = GROUP A BY a;
    • 使用欄位 a 的資料做分類

6 - 2

A = LOAD '/teaching/b.txt' using PigStorage(',') AS (a:int, b:int, c:int, d:int, e:int, f:int);

B = GROUP A BY a;

DUMP B;
(1,{(1,2,3,6,9,8),(1,2,3,5,9,6)})
(3,{(3,2,4,8,9,5),(3,6,9,8,5,4)})
(5,{(5,9,6,3,5,8),(5,9,6,2,4,8)})

DESCRIBE B;
B: {group: int,A: {(a: int,b: int,c: int,d: int,e: int,f: int)}}

C = FOREACH B GENERATE group, COUNT(A);

DUMP C;
(1,2)
(3,2)
(5,2)

DESCRIBE C;
C: {group: int,long}
  • C = FOREACH B GENERATE group, COUNT(A);
    • 這邊的 group 並不是 關鍵字(Keyword) 而是 $0 的一個欄位名稱而已 , 如果 DESCRIBE B; 出來的架構是 B: {NewName: int,A: {(a: int,b: int,c: int,d: int,e: int,f: int)}} 而我們的敘述就要改成 C = FOREACH B GENERATE NewName, COUNT(A);
    • COUNT(A) 就是剛剛說得計算功能 , 他只能計算 包(Bags) 裡面有幾個 元組(Tuples) , 所以在這邊就是分別計算出 $01 的資料有幾個 3 的有幾個 5 的有幾個
  • DUMP C;
    (1,2)
    (3,2)
    (5,2)
    • 所以這邊就可以知道 $01 的資料有 23 的資料有 2 5 的資料也有 2
  • DESCRIBE C;
    C: {group: int,long}
    • COUNT() 所算來的資料類型預設是 long

6 - 3

A = LOAD '/teaching/b.txt' using PigStorage(',') AS (a:int, b:int, c:int, d:int, e:int, f:int);

B = GROUP A ALL;

DUMP B;
(all,{(1,2,3,6,9,8),(1,2,3,5,9,6),(5,9,6,3,5,8),(5,9,6,2,4,8),(3,2,4,8,9,5),(3,6,9,8,5,4)})

DESCRIBE B;
B: {group: chararray,A: {(a: int,b: int,c: int,d: int,e: int,f: int)}}

C = FOREACH B GENERATE group, COUNT(A);

DUMP C;
(all,6)

DESCRIBE C;
C: {group: chararray,long}
  • B = GROUP A ALL;
    • 這便要示範的是把每一筆資料都 包(Bags) 起來
  • DUMP B;
    (all,{(1,2,3,6,9,8),(1,2,3,5,9,6),(5,9,6,3,5,8),(5,9,6,2,4,8),(3,2,4,8,9,5),(3,6,9,8,5,4)})
    • 這邊看到他麼資料是一個 ALL + 你原本的資料
  • C = FOREACH B GENERATE group, COUNT(A);
    • 這邊他保留了前面的 ALL 並且計算 包(Bags) 裡面有幾個 元組(Tuples)
  • DUMP C;
    (all,6)
    • 這樣做就是要資料我們讀進去的檔案總共有幾筆資料 , 所以這邊顯示出來我們全部有 6 筆資料

6 - 4

這邊個範例比較特別所以我直接在範例內用註解做解說
不知道各位有沒有想過在 包(Bags) 裡面的 元組(Tuples) 要如何處理呢?這著範例就是要教大家怎麼處理 包(Bags) 的資料 , 我自己在學的時候也是搞了好久才搞定的

A = LOAD '/teaching/b.txt' using PigStorage(',') AS (a:int, b:int, c:int, d:int, e:int, f:int);

B = GROUP A BY a;

DUMP B;
(1,{(1,2,3,6,9,8),(1,2,3,5,9,6)})
(3,{(3,2,4,8,9,5),(3,6,9,8,5,4)})
(5,{(5,9,6,3,5,8),(5,9,6,2,4,8)})

DESCRIBE B;
B: {group: int,A: {(a: int,b: int,c: int,d: int,e: int,f: int)}}

C = FOREACH B{

  C1 = FOREACH A GENERATE (a+b+c+d+e+f);

  GENERATE group, C1;

  -- GENERATE 是關鍵字不能改而且必須放在最後做結尾 group 是上面 $0 的名字 C1 則是你在 { } 做的敘述句代號 , 外面能做的函式在這邊基本上都可以執行但只能操作 包(Bags) 的資料 
}

DUMP C;
(1,{(29),(26)})
(3,{(31),(35)})
(5,{(36),(34)})

DESCRIBE C;
C: {group: int,C1: {(int)}}

D = FOREACH B{

  C1 = FOREACH A GENERATE (a+b+c+d+e+f);

  GENERATE C1;
  -- 如果沒有打上 group 就不會出現前面的 1 3 5 了 , 只會留下剛剛全部加起來的數字在 包(Bags) 裡面
}

DUMP D;
({(29),(26)})
({(31),(35)})
({(36),(34)})


DESCRIBE D;
D: {C1: {(int)}}

COUNT

這是一個用來計算 包(Bags) 裡面有多少個 元組(Tuples) , 但是如果 包(Bags) 裡面有 NULL(空值) 是會被忽略的

語法

[代號] = FOREACH [代號] GENERATE COUNT([欄位名稱]);

範例

7 - 1

A = LOAD '/teaching/c.txt' using PigStorage(',') AS (dates:chararray, catid:int, userid:chararray);

B = GROUP A ALL;

C = FOREACH B GENERATE $1;

D = FOREACH C GENERATE COUNT(A);

DUMP C;
({(20150922,17,u016045383),(20150821,1,u015769781),(20150710,8,u008137791),(20150830,18,u014711537),(20150627,1,u014616537),(20150830,2,u007591963),(20150726,38,u014540733),(20150715,40,u014792743),(20150627,12,u006343463),(20150707,18,u005655603),(20150911,5,u008969559),(20150820,18,u015235929),(20150919,40,u003234985),(20150602,39,u008469313),(20150617,40,u201308777),(20150916,21,u002529119)})

DUMP D;
(16)

DESCRIBE D;
D: {long}
  • B = GROUP A ALL;

    • 把全部資料 包(Bags) 起來
  • C = FOREACH B GENERATE $1;

    • 去掉資料第一個欄位 ( $0 ) 的 ALL 字串
  • D = FOREACH C GENERATE COUNT(A);

    • 算出資料總筆數

TOTUPLE

TOTUPLE 用來將 字段(Fields) 組合成 元組(Tuples)

語法

[代號] = FOREACH [代號] GENERATE TOTUPLE([欄位]);

範例

8 - 1

A = LOAD '/teaching/b.txt' using PigStorage(',') AS (a:int, b:int, c:int, d:int, e:int, f:int);

B = FOREACH A GENERATE TOTUPLE(a, b), c, d, TOTUPLE(e, f);

DUMP B;
((1,2),3,6,(9,8))
((1,2),3,5,(9,6))
((5,9),6,3,(5,8))
((5,9),6,2,(4,8))
((3,2),4,8,(9,5))
((3,6),9,8,(5,4))
  • B = FOREACH A GENERATE TOTUPLE(a, b), c, d, TOTUPLE(e, f);
    • 將要 元組(Tuples)字段(Fields) 加入 TOTUPLE() , 並且需要配合 FOREACH 使用

FLATTEN

FLATTEN 是用來將 元組(Tuples) 拆解成 字段(Fields) , 也可以把 group 起來的資料復原!

語法

[代號] = FOREACH [代號] GENERATE FLATTEN([欄位]);

範例

9 - 1

A = LOAD '/teaching/b.txt' using PigStorage(',') AS (a:int, b:int, c:int, d:int, e:int, f:int);

B = FOREACH A GENERATE TOTUPLE(a, b), c, d, TOTUPLE(e, f);

C = FOREACH B GENERATE FLATTEN($0), c, d, FLATTEN($3);

DUMP B;
((1,2),3,6,(9,8))
((1,2),3,5,(9,6))
((5,9),6,3,(5,8))
((5,9),6,2,(4,8))
((3,2),4,8,(9,5))
((3,6),9,8,(5,4))

DUMP C;;
(1,2,3,6,9,8)
(1,2,3,5,9,6)
(5,9,6,3,5,8)
(5,9,6,2,4,8)
(3,2,4,8,9,5)
(3,6,9,8,5,4)
  • B = FOREACH A GENERATE TOTUPLE(a, b), c, d, TOTUPLE(e, f);

    • 使用上一節的程式
  • C = FOREACH B GENERATE FLATTEN($0), c, d, FLATTEN($3);

    • 依照 DUMP B 的結果得知 (1,2) 是排在 $0 , (9,8)$3 所以就分別在 FLATTEN() 填入 $0$3

9 - 2

A = LOAD '/teaching/b.txt' using PigStorage(',') AS (a:int, b:int, c:int, d:int, e:int, f:int);

B = GROUP A BY a;

C = FOREACH B GENERATE FLATTEN(A);

DUMP B;
(1,{(1,2,3,6,9,8),(1,2,3,5,9,6)})
(3,{(3,2,4,8,9,5),(3,6,9,8,5,4)})
(5,{(5,9,6,3,5,8),(5,9,6,2,4,8)})

DUMP C;
(1,2,3,6,9,8)
(1,2,3,5,9,6)
(3,2,4,8,9,5)
(3,6,9,8,5,4)
(5,9,6,3,5,8)
(5,9,6,2,4,8)
  • B = GROUP A BY a;

    • 依照 a 將資料 GROUP 起來
  • C = FOREACH B GENERATE FLATTEN(A);

    • 因為是用 aGROUP 所以在 FLATTEN() 中填入 a 就可以把它復原

9 - 3

A = LOAD '/teaching/b.txt' using PigStorage(',') AS (a:int, b:int, c:int, d:int, e:int, f:int);

B = GROUP A BY a;

C = FOREACH B GENERATE BagToTuple(A);

D = FOREACH B GENERATE FLATTEN(BagToTuple(A));

DUMP B;
(1,{(1,2,3,6,9,8),(1,2,3,5,9,6)})
(3,{(3,2,4,8,9,5),(3,6,9,8,5,4)})
(5,{(5,9,6,3,5,8),(5,9,6,2,4,8)})

DUMP C;
((1,2,3,6,9,8,1,2,3,5,9,6))
((3,2,4,8,9,5,3,6,9,8,5,4))
((5,9,6,3,5,8,5,9,6,2,4,8))


DUMP D;
(1,2,3,6,9,8,1,2,3,5,9,6)
(3,2,4,8,9,5,3,6,9,8,5,4)
(5,9,6,3,5,8,5,9,6,2,4,8)
  • C = FOREACH B GENERATE BagToTuple(A);

    • BagToTuple(A) 可以把 GROUP 的資料解出來 , 但是會把資料包成 元組(Tuples)
  • D = FOREACH B GENERATE FLATTEN(BagToTuple(A));

    • 由上面的敘述可以知道 BagToTuple(A) 可以轉成 元組(Tuples) , 而 FLATTEN() 就是把 BagToTuple(A) 轉出來的 元組(Tuples) 繼續轉成 字段(Fields)

ORDER

依照指定的 [欄位] 做排序

語法

[代號] = ORDER [代號] BY [欄位] [ASC|DESC];

範例

10 - 1

A = LOAD '/teaching/b.txt' using PigStorage(',') AS (a:int, b:int, c:int, d:int, e:int, f:int);

B = ORDER A BY a ASC, d DESC;

DUMP B;
(1,2,3,6,9,8)
(1,2,3,5,9,6)
(3,2,4,8,9,5)
(3,6,9,8,5,4)
(5,9,6,3,5,8)
(5,9,6,2,4,8)
  • B = ORDER A BY a ASC, d DESC;
    • 可以只排列一個欄位 , 也可以排列兩個欄位甚至是更多個欄位 , 並且可以分別指定排序方式
    • a ASC 將欄位 a 由小排到大
    • d DESC 將欄位 d 由大排到小

10 - 2

A = LOAD '/teaching/b.txt' using PigStorage(',') AS (a:int, b:int, c:int, d:int, e:int, f:int);

B = GROUP A BY a;

C = FOREACH B {
  C1 = ORDER A BY $3 ASC;
  GENERATE group, C1;
}

DUMP B;
(1,{(1,2,3,6,9,8),(1,2,3,5,9,6)})
(3,{(3,2,4,8,9,5),(3,6,9,8,5,4)})
(5,{(5,9,6,3,5,8),(5,9,6,2,4,8)})

DUMP C;
(1,{(1,2,3,5,9,6),(1,2,3,6,9,8)})
(3,{(3,2,4,8,9,5),(3,6,9,8,5,4)})
(5,{(5,9,6,2,4,8),(5,9,6,3,5,8)})
  • C1 = ORDER A BY $3 ASC;
    • 在還沒有看解說之前你可羺會以為這邊的 ORDER 會改變每一個 元組(Tuples) 內的資料排序 , 但其實不是這樣的 , 這邊的 ORDER 是換改變每一個 元組(Tuples)包(Bags) 裡面的順序 , 完全不會動到 元組(Tuples) 內的資源 , 所以不用擔心資料會亂掉

UNION

將兩份文件或是兩個結果二合一的第一種辦法也是最簡單的辦法

語法

[代號] = UNION [代號], [代號];

範例

11 - 1

A = LOAD '/teaching/a.txt' using PigStorage(',') AS (a:int, b:int, c:int);

B = LOAD '/teaching/b.txt' using PigStorage(',') AS (a:int, b:int, c:int, d:int, e:int, f:int);

C = UNION A, B;

DUMP C;
(1,2,3,6,9,8)
(1,2,3,5,9,6)
(5,9,6,3,5,8)
(5,9,6,2,4,8)
(3,2,4,8,9,5)
(3,6,9,8,5,4)
(1,2,3)
(4,5,6)
  • C = UNION A, B;
    • 資料載入後就直接合體(?

11 - 2

A = LOAD '/teaching/a.txt' using PigStorage(',') AS (a:int, b:int, c:int);

B = LOAD '/teaching/b.txt' using PigStorage(',') AS (a:int, b:int, c:int, d:int, e:int, f:int);

C = FOREACH B GENERATE a, b, c;

D = UNION A, C;

DUMP D;
(1,2,3)
(4,5,6)
(1,2,3)
(1,2,3)
(5,9,6)
(5,9,6)
(3,2,4)
(3,6,9)
  • D = UNION A, C;
    • 處理過後的結果當然也可以拿來合體!

DISTINCT

移除重複的資料

語法

[代號] = DISTINCT [代號];

範例

12 - 1

A = LOAD '/teaching/a.txt' using PigStorage(',') AS (a:int, b:int, c:int);

B = LOAD '/teaching/b.txt' using PigStorage(',') AS (a:int, b:int, c:int, d:int, e:int, f:int);

C = FOREACH B GENERATE a, b, c;

D = UNION A, C;

E = DISTINCT D;

DUMP D;
(1,2,3)
(4,5,6)
(1,2,3)
(1,2,3)
(5,9,6)
(5,9,6)
(3,2,4)
(3,6,9)

DUMP E;
(1,2,3)
(3,2,4)
(3,6,9)
(4,5,6)
(5,9,6)
  • E = DISTINCT D;
    • 移除掉 D 中重複的料

CROSS

這也是將兩個檔案或是結果二合一的方法之一 , 但是比 UNION 還要進階一點 , 用說的解釋比較抽象也不好了解 , 所以就直接來看看範例吧!

語法

[代號] = CROSS [代號], [代號];

範例

13 - 1

A = LOAD '/teaching/a.txt' using PigStorage(',') AS (a:int, b:int, c:int);

B = LOAD '/teaching/b.txt' using PigStorage(',') AS (a:int, b:int, c:int, d:int, e:int, f:int);

D = CROSS B, A;

E = CROSS A, B;

DUMP D;
(5,9,6,2,4,8,1,2,3)
(5,9,6,2,4,8,4,5,6)
(5,9,6,3,5,8,1,2,3)
(5,9,6,3,5,8,4,5,6)
(1,2,3,6,9,8,1,2,3)
(3,6,9,8,5,4,1,2,3)
(3,6,9,8,5,4,4,5,6)
(1,2,3,6,9,8,4,5,6)
(3,2,4,8,9,5,1,2,3)
(1,2,3,5,9,6,1,2,3)
(3,2,4,8,9,5,4,5,6)
(1,2,3,5,9,6,4,5,6)

DUMP E;
(4,5,6,1,2,3,6,9,8)
(4,5,6,1,2,3,5,9,6)
(4,5,6,5,9,6,3,5,8)
(4,5,6,5,9,6,2,4,8)
(4,5,6,3,2,4,8,9,5)
(4,5,6,3,6,9,8,5,4)
(1,2,3,5,9,6,3,5,8)
(1,2,3,1,2,3,6,9,8)
(1,2,3,1,2,3,5,9,6)
(1,2,3,5,9,6,2,4,8)
(1,2,3,3,6,9,8,5,4)
(1,2,3,3,2,4,8,9,5)
  • D = CROSS B, A;

    • b 文件第一筆資料是 5,9,6,2,4,8
    • a 文件第一筆資料是 1,2,3
    • a 文件第二筆資料是 4,5,6
    • 所以當 BA 前面時 b 的第一筆資料會依序接上 a 的兩比資料 , 所以才會出現 (5,9,6,2,4,8,1,2,3)(5,9,6,2,4,8,4,5,6) 這兩比資料
  • E = CROSS A, B;

    • AB 前面時所合出來的檔案也會有位置的不同 , 這間就請各位同學自己了解一下資料的規則吧 , 其實一點也不難

SUM

包(Bags) 裡面的數字做加法

語法

[代號] = FOREACH [代號] GENERATE SUM([代號].[欄位]);

範例

14 - 1

A = LOAD '/teaching/d.txt' using PigStorage(',') AS (owner:chararray, pet_type:chararray, pet_num:int);

B = GROUP A BY owner;

C = FOREACH B GENERATE group, SUM(A.pet_num);

DUMP B;
(Alice,{(Alice,turtle,1),(Alice,goldfish,5),(Alice,cat,2)})
(Bob,{(Bob,dog,2),(Bob,cat,2)})

DUMP C;
(Alice,8)
(Bob,4)
  • C = FOREACH B GENERATE group, SUM(A.pet_num);
    • SUM(A.pet_num) 中的 A 就是被我們 GROUP 起來的代號 , 而 pet_num 就是我們要計算的欄位名稱 , 記得資料的類型絕對不可以是 chararray 不然會出現錯誤 , 因為文字是不能相加的

SIZE

用於計算 [欄位] 中得 chararray 資料類型共有幾個字

語法

[代號] = FOREACH [代號] GENERATE SIZE([欄位]);

範例

15 - 1

A = LOAD '/teaching/d.txt' using PigStorage(',') AS (owner:chararray, pet_type:chararray, pet_num:int);

B = FOREACH A GENERATE SIZE(pet_type);

C = FOREACH A GENERATE SIZE(pet_num);

DUMP B;
(6)
(8)
(3)
(3)
(3)

DUMP C;
(1)
(1)
(1)
(1)
(1)
  • B = FOREACH A GENERATE SIZE(pet_type);

    • 計算 pet_type 的字數
  • C = FOREACH A GENERATE SIZE(pet_num);

    • 當然數字類型的資料也可以計算

MAX

包(Bags) 裡面取最大的一個值

語法

[代號] = FOREACH [代號] GENERATE MAX([代號].[欄位]);

範例

16 - 1

A = LOAD '/teaching/e.txt' using PigStorage(',') AS (name:chararray, session:chararray, gpa:float);

B = GROUP A BY name;

C = FOREACH B GENERATE group, MAX(A.gpa);

DUMP B;
(John,{(John,fl,3.9),(John,wt,3.7),(John,sp,4.0),(John,sm,3.8)})
(Mary,{(Mary,fl,3.8),(Mary,wt,3.9),(Mary,sp,4.0),(Mary,sm,4.0)})

DUMP C;

(John,4.0)
(Mary,4.0)
  • C = FOREACH B GENERATE group, MAX(A.gpa);
    • 語法與上面的 SUM 有點類似只是 MAX 是要抓出最大的那個值

MIN

包(Bags) 裡面取最小的一個值

語法

[代號] = FOREACH [代號] GENERATE MIN([代號].[欄位]);

範例

17 - 1

A = LOAD '/teaching/e.txt' using PigStorage(',') AS (name:chararray, session:chararray, gpa:float);

B = GROUP A BY name;

C = FOREACH B GENERATE group, MIN(A.gpa);

DUMP B;
(John,{(John,fl,3.9),(John,wt,3.7),(John,sp,4.0),(John,sm,3.8)})
(Mary,{(Mary,fl,3.8),(Mary,wt,3.9),(Mary,sp,4.0),(Mary,sm,4.0)})

DUMP C;
(John,3.7)
(Mary,3.8)
  • C = FOREACH B GENERATE group, MIN(A.gpa);
    • 有取出最大當然有取出最小的了

TOBAG

TOBAG 輸出的結果跟 TOTUPLE 有點類似 , 只是他不只包成 元組(Tuples) 還會更進一步的包成 包(Bags)

語法

[代號] = FOREACH [代號] GENERATE TOBAG([欄位]);

範例

18 - 1

A = LOAD '/teaching/e.txt' using PigStorage(',') AS (name:chararray, session:chararray, gpa:float);

B = FOREACH A GENERATE TOBAG(name, gpa);

DUMP B;
({(John),(3.9)})
({(John),(3.7)})
({(John),(4.0)})
({(John),(3.8)})
({(Mary),(3.8)})
({(Mary),(3.9)})
({(Mary),(4.0)})
({(Mary),(4.0)})
  • B = FOREACH A GENERATE TOBAG(name, gpa);
    • TOBAG(name, gpa) 將欄位 namegpa 分別包成 元組(Tuples) 在放入一個 包(Bags)

DIFF

依序比較兩個 包(Bags) 裡面的 元組(Tuples) 取出不一樣的 , 如果沒有不一樣的會直接顯示 null

語法

[代號] = FOREACH [代號] GENERATE DIFF([欄位]);

範例

19 - 1

A = LOAD '/teaching/f.txt' using PigStorage(',') as (a:int, b:int, c:int, d:int, e:int, f:int, g:int , h:int);

B = FOREACH A GENERATE TOTUPLE(a, b), TOTUPLE(c, d), TOTUPLE(e, f), TOTUPLE(g, h);

C = FOREACH B GENERATE TOBAG($0, $1), TOBAG($2, $3);

D = FOREACH C GENERATE DIFF($0,$1);

DUMP C;
({(8,9),(0,1)},{(8,9),(1,1)})
({(2,3),(4,5)},{(2,3),(4,5)})
({(6,7),(3,7)},{(2,2),(3,7)})

DUMP D;
({(0,1),(1,1)})
({})
({(6,7),(2,2)})
  • DUMP C;

    • 這邊 DUMP 的資料是有經過處理的 , 而這些處理的步驟在上的教學都有 , 不懂的同學看上面教學
  • D = FOREACH C GENERATE DIFF($0,$1);

    • 這裡我們要用 {(8,9),(0,1)}{(8,9),(1,1)} 兩個來做比較 , 其中 (0,1)(1,1) 不同所以會被抓出來
    • 比較值得注意的是 ({}) 為什麼是空白 , 其實很簡單因為 (2,3),(4,5)(2,3),(4,5) 完全一樣 , 所以當然給你 NULL

  1. Notepad++ 是一個非常好用的 Text Edit 詳細的使用方式就請各位自己 Google
  2. Emacs 是在 Linux 上面也是一個我很推薦的 Text Edit 可以提供 Pig 高亮度語法 ( 有機會會在另外介紹 )