2013-05-09 71 views
1

使用Apache豬版本0.10.1.21(rexported)數據樣本文件的Pig Load如何混合標量和映射數據類型?

內容:

AtomicNumber,ElementName,Symbol,AtomicMass,PropertyMap 
46,Palladium,Pd,106.42,[P#46,N#60,Struc#Cubic] 
49,Indium,In,114.818,[P#49,N#66,Struc#Tetragonal] 
52,Tellurium,Te,127.6,[P#52,N#76,Struc#Hexagonal] 
86,Radon,222.0,Rn,[P#86,N#136,Struc#Cubic] 
38,Strontium,Sr,87.62,[P#38,N#50,Struc#Cubic] 
Plutonium,94,Pu,244.0,[P#94,N#150,Struc#Monoclinic] 

注:某些列特意換(氡和鈈)怎麼看豬手柄數據類型不匹配

豬腳本:

AtomElem = LOAD 'data/Atoms.txt' USING PigStorage(',') AS (AtomicNumber:int, ElementName:chararray, Symbol:chararray, AtomicMass:float, PropertyMap:map[]); 
DUMP AtomElem; 

結果:

(,ElementName,Symbol,,) 
(46,Palladium,Pd,106.42,) 
(49,Indium,In,114.818,) 
(52,Tellurium,Te,127.6,) 
(86,Radon,222.0,,) 
(38,Strontium,Sr,87.62,) 
(,94,Pu,244.0,) 

Question1:我希望能夠顯示PropertyMap。你能告訴我如何修改豬腳本或數據文件,以便將PropertyMap列顯示爲地圖數據類型。

Question2:在地圖模式的聲明中,我想強類型的數據類型。我將模式聲明爲PropertyMap:map [int,int,chararray],但豬已經拒絕了語法(錯誤,預期的右括號)。是否可以聲明有幾個鍵的地圖?如果是的話,模式聲明應該是什麼樣子?

在此先感謝您的幫助。

回答

1

您的腳本未能成功生成地圖的原因是您已將逗號用作字段分隔符,但它也是地圖鍵值對的分隔符。所以,當豬把你的線分成幾個字段時,第五個字段不是[P#46,N#60,Struc#Cubic],正如你所期望的那樣,而是它是[P#46。豬無法成功地將其解析爲地圖,因此將其轉換爲NULL

至於你的第二個問題,你不能指定個別映射值的數據類型。首先,訂單在地圖上沒有任何意義。地圖可以有任意數量的元素。如果你想爲所有的值指定一個數據類型,你可以這樣做,但除此之外,Pig都會知道它是什麼類型,或者當你使用它時需要明確地轉換值。爲了說明這兩點,我將輸入數據修改爲製表符分隔(並相應地將腳本更新爲USING PigStorage('\t')),並在第二行中交換了兩個地圖元素的位置以顯示Pig不重現他們提供的順序。

$ cat data.txt 
AtomicNumber ElementName  Symbol AtomicMass  PropertyMap 
46  Palladium  Pd  106.42 [P#46,N#60,Struc#Cubic] 
49  Indium In  114.818 [N#66,Struc#Tetragonal,P#49] 
52  Tellurium  Te  127.6 [P#52,N#76,Struc#Hexagonal] 
86  Radon 222.0 Rn  [P#86,N#136,Struc#Cubic] 
38  Strontium  Sr  87.62 [P#38,N#50,Struc#Cubic] 
Plutonium  94  Pu  244.0 [P#94,N#150,Struc#Monoclinic] 

$ cat test.pig 
AtomElem = LOAD 'data.txt' USING PigStorage('\t') AS (AtomicNumber:int, ElementName:chararray, Symbol:chararray, AtomicMass:float, PropertyMap:map[]); 
DUMP AtomElem; 

$ pig -x local test.pig 
(,ElementName,Symbol,,) 
(46,Palladium,Pd,106.42,[P#46,N#60,Struc#Cubic]) 
(49,Indium,In,114.818,[P#49,N#66,Struc#Tetragonal]) 
(52,Tellurium,Te,127.6,[P#52,N#76,Struc#Hexagonal]) 
(86,Radon,222.0,,[P#86,N#136,Struc#Cubic]) 
(38,Strontium,Sr,87.62,[P#38,N#50,Struc#Cubic]) 
(,94,Pu,244.0,[P#94,N#150,Struc#Monoclinic]) 
+0

精彩的回答,非常感謝您花時間重寫我的測試用例。它完美的作品。瞭解Q2的說明。 – Polymerase 2013-05-10 01:49:39

+0

你能幫我多一點嗎?我使用這個腳本來顯示地圖上的值,但是在'#'處或附近得到語法錯誤,意外符號。對不起,但我怎樣才能在這個評論部分輸入代碼?!?!? – Polymerase 2013-05-10 05:56:09

+0

嘗試詢問一個新問題併發布準確的代碼和數據。這聽起來像錯誤是指代碼中的數字符號。 – 2013-05-10 21:43:35

0

就個人而言,我會將所有數據存儲爲JSON並從中加載。當你在加載的數據集中有複雜的數據結構時,它會爲你和後來的任何工作人員管理起來更容易,因爲JSON是比加載地圖等更加直接的嵌套結構標準。豬。

我認爲@WinnieNicklaus的答案應該可以,但下一個工作的人或下一次需要添加一些複雜的數據時,會遇到同樣的問題。只是存儲在JSON一切,負載Pig's Built-in JSON loader

a = load 'a.json' using 
JsonLoader('a0:int,a1:{(a10:int,a11:chararray)},a2:(a20:double,a21:bytearray),a3:[chararray]'); 

如果你不想提供一個模式,你也可以加載使用ElephantBird的JSON裝載機:

loaded = LOAD '/path/to/some_file.json' 
    using com.twitter.elephantbird.pig.load.JsonLoader('-nestedLoad'); 

這兩項都應該正常工作如果我沒有記錯的話,使用.gz文件,而elephantbird版本也適用於lzos。

+0

感謝您提供JSON加載程序。當我更熟悉Pig Latin時,肯定會嘗試。 – Polymerase 2013-05-10 01:51:23