2013-12-10 45 views
1

我正在使用Pig 0.8.1。我對Pig有點新,但是我知道必須有一個合理且可重用的解決方案來處理我想如何使用我的元組。我有以下的格式(類似於三元):將豬中的許多鍵/值元組合併成單個元組

Schema: (uuid, key, val) 

Data: 
(id1, 'name', 'Corey') 
(id1, 'location', 'USA') 
(id1, 'carsOwned', 5) 
(id2, 'name', 'Paul') 
(id2, 'location', 'CANADA') 
(id2, 'carsOwned', 10) 

我代表三元該數據的原因是因爲它可能具有多值鍵,因此數據推入地圖出來的題。

我需要做的是找到擁有前10輛車的人的ID,姓名和位置。我想,如果我的輸出格式可以此按降序排序時:

Schema: (uuid, name, location, carsOwned) 

Data: 
(id2, 'Paul', 'CANADA', 10) 
(id1, 'Corey', 'USA', 5) 

我已經試過我的濾波輸入到3名不同的別名(即一個鍵==「名」,一個關鍵的地方== 'location'和一個key =='carsOwned'),這樣我就可以使用JOIN並將它們帶回到一個元組中,但看起來Pig最終會從inputFormat中加載3次而不是1次。也許我做錯了?

我也試着按ID分組,但是我似乎無法找到合理的方式來處理實際的三鍵/值的包,因爲它們都具有完全相同的模式。

我真正想要的是按ID字段進行分組,然後將每個按鍵扁平化,但將別名重命名爲鍵的實際名稱。

任何想法?提前致謝!

回答

2

這個解決方案有點草率,因爲你的數據的組織方式並不是Pig真正設置的 - 也就是說,在概念上,每個id顯示都是一個行鍵,並且用你在第二列。但只要您的數據合理,這仍然可以完成。如果錯誤地使用相同的id和字段名稱但具有不同的值的多行結束,這將變得複雜。

使用嵌套的foreach挑出來的值,你感興趣的三個方面。

keyedByID = 
    /* Gather the rows by ID, then process each one in turn */ 
    FOREACH (GROUP Data BY id) { 
     /* Pull out the fields you want. If you have duplicate rows, 
      you'll need to use a LIMIT statement to ensure just a single record */ 
     name = FILTER Data BY field == 'name'; 
     location = FILTER Data BY field == 'location'; 
     carsOwned = FILTER Data BY field == 'carsOwned'; 
    GENERATE 
     /* Output each field you want. You'll need to use FLATTEN since 
      the things created above in the nested foreach are bags. */ 
     group AS id, 
     FLATTEN(name) AS name, 
     FLATTEN(locatioN) AS location, 
     FLATTEN(carsOwned) AS carsOwned; 
    }; 

現在你已經有了將所有信息的ID在同一行上的關係,你可以隨心所欲地做任何事情。例如,你說要拔出前10名車主:

ordered = ORDER keyedByID BY carsOwned DESC; 
top10 = LIMIT ordered 10; 
+0

這很好。謝謝! –