2013-11-26 61 views
1
聯接給予threashold在Hadoop中

比方說,我有以下模式的數據集:我怎會用PIG

ItemName (String) , Length (long) 

我需要找到是基於它們的長度重複的情況。這在PIG中很容易做到:

raw_data = LOAD...dataset 
grouped = GROUP raw_data by length 
items = FOREACH grouped GENERATE COUNT(raw_data) as count, raw_data.name; 
dups = FILTER items BY count > 1; 
STORE dups.... 

以上查找確切的重複項。鑑於設置波紋管: 一個,100 B,105 C,100

它將輸出2,(A,C)

現在我需要找到使用閾值重複。例如5閾值將意味着比賽的項目,如果它們的長度+/- 5所以輸出應該是這樣的:

3,(A,B,C)

任何想法我怎麼能去這樣做這個?

這幾乎就像我想PIG使用UDF作爲其comparator當其join期間比較記錄...

回答

0

我覺得做你想要什麼的唯一方式是將數據加載爲兩個表,並將數據集笛卡爾連接到自身,以便每個值都可以與其他值進行比較。

僞代碼:

r1 = load dataset 
r2 = load dataset 
rcross = cross r1, r2 

rcross是笛卡兒積,將允許你檢查每一對之間的長度差。

0

我一次解決了類似的問題,並得到了一個瘋狂和骯髒的解決方案。 它是基於下一引理:

If |a - b| < r then there exists such an integer number x: 0 <= x < r that 
floor((a+x)/r) = floor((b+x)/r) 

(進一步我將意味着只有整數除法,並且將省略地板()函數,即5/2 = 2)

這引理是顯而易見的,I」中號不是要去證明它在這裏

基於這一引理你可以做下一個加入:

RESULT = JOIN A by A.len/r, B By B.len/r 

並獲得幾個值從全部對應的值| A.len - B.len | < [R

但這樣做[R時間:

RESULT0 = JOIN A by A.len/r, B By (B.len/r) 
RESULT1 = JOIN A by (A.len+1)/r, B By (B.len+1)/r 
... 
RESULT{R-1} = JOIN A by (A.len+r-1)/r, B By (B.len+r-1)/r 

你會得到所有需要的值。當然,你會得到比你需要更多的行,但正如我所說已經是一個骯髒的解決方案(即它不是最佳的,但工程)

該解決方案的另一個大缺點是JOIN應該動態編寫,將大爲大r。 不過它的作品,如果你知道[R,它是相當小的(像你的情況R = 6)

希望它可以幫助