2013-09-25 13 views
12

Sütunların bir alt kümesinde DISTINCT işlemi gerçekleştirmek istiyorum. documentation bu iç içe geçmiş bir foreach ile ulaşılabileceğini söyledi:Sütunların bir alt kümesinde Pig Latince DISTINCT nasıl gerçekleştirilir?

Sen alanların bir alt kümesi üzerinde DISTINCT kullanamazsınız; Bunu yapmak için, FOREACH ve yuvalanmış bir bloğu ilk önce alanları seçin ve sonra DISTINCT'ı uygulayın (Örnek: İç içe geçmiş blok).

sütunların tümü üzerinde DISTINCT işlemi gerçekleştirmek için basittir:

A = LOAD 'data' AS (a1,a2,a3,a4); 
A_unique = DISTINCT A; 

ben a1, a2 ve a3 genelinde farklı performans ilgileniyorum olduğunu düşünelim. Bu işlemin, belgelerde önerildiği gibi yuvalanmış bir foreach ile nasıl gerçekleştirileceğini gösteren bir örnek sağlanabilir mi?

İşte bir girişin örneği ve beklenen çıkışı var: Burada

A = LOAD 'data' AS(a1,a2,a3,a4); 
DUMP A; 

(1 2 3 4) 
(1 2 3 4) 
(1 2 3 5) 
(1 2 4 4) 

-- insert DISTINCT operation on a1,a2,a3 here: 
-- ... 

DUMP A_unique; 

(1 2 3 4) 
(1 2 4 4) 
+2

Eğer örnek girişi ve beklenen çıkışı verebilir misiniz? – zero323

+0

İyi öneri, soruyu güncelledim. – Freerobots

cevap

18

Grup, bir torbaya ilgi projesi sadece sütunlar, ve sonra onları tekrar genişletmek için FLATTEN kullanın:

A_unique = 
    FOREACH (GROUP A BY a4) { 
     b = A.(a1,a2,a3); 
     s = DISTINCT b; 
     GENERATE FLATTEN(s), group AS a4; 
    }; 
+0

Çok güzel örnek! Yardım için teşekkürler. Bu, cevabımla gerçekten farklı bir şekilde benzer, ama çok daha özlü. – Freerobots

+0

Paralel yan tümceleri nasıl etkinleştirebiliriz? Scriptimde DEFAULT_PARALLEL 512 kullanmayı denedim ama işe yaramadı ve redüktörler 512 ile sınırlı değil. – TopCoder

0

2 olası çözümler aşağıda başka iyi yaklaşım vardır?

Çözüm 1 (SINIRLAMASINI 1 kullanarak):

A = LOAD 'test_data' AS (a1,a2,a3,a4); 

-- Combine the columns that I want to perform the distinct across into a tuple 
A2 = FOREACH A GENERATE TOTUPLE(a1,a2,a3) AS combined, a4 as a4 

-- Group by the combined column 
grouped_by_a4 = GROUP A2 BY combined; 

grouped_and_distinct = FOREACH grouped_by_a4 { 
     single = LIMIT A2 1; 
     GENERATE FLATTEN(single); 
}; 

Çözüm 2 (DISTINCT kullanarak):

tüm diğer sütunları
A = LOAD 'test_data' AS (a1,a2,a3,a4); 

-- Combine the columns that I want to perform the distinct across into a tuple 
A2 = FOREACH A GENERATE TOTUPLE(a1,a2,a3) AS combined, a4 as a4 

-- Group by the other columns (those I don't want the distinct applied to) 
grouped_by_a4 = GROUP A2 BY a4; 

-- Perform the distinct on a projection of combined and flatten 
grouped_and_distinct = FOREACH grouped_by_a4 { 
     combined_unique = DISTINCT A2.combined; 
     GENERATE FLATTEN(combined_unique); 
}; 
+0

Bu çözümler eşdeğer değildir. Birincisi sadece iki tuple verecektir, çünkü "a1", "a2" ve "a3" 'ün iki benzersiz kombinasyonu vardır ve a4'ün değeri öngörülebilir değildir. İkinci örnek çıktı ile tutarlı çıktı verecektir. (Gerçi olabileceği kadar kısa değil.) –

1

belirttiğiniz için giriş/çıkış, aşağıdaki işler. İhtiyacınız olanı bundan daha farklı kılmak için test vektörlerinizi güncelleyebilirsiniz.

A_unique = DISTINCT A; 
+0

Evet, yardımcı olabilir :). Asıl soruda beklenen çıktıyı güncelledim. – Freerobots

2

kabul cevap durumda bu işe yaramayabilir (Geçenlerde yapmak zorunda şey) çıktıda alanları yeniden sıralamak istiyorum, insana büyük bir çözümdür ama. İşte bir alternatiftir:

A = LOAD '$input' AS (f1, f2, f3, f4, f5); 
GP = GROUP A BY (f1, f2, f3); 
OUTPUT = FOREACH GP GENERATE 
    group.f1, group.f2, f4, f5, group.f3 ; 

belirli alanlarda grup, seçim bir her demet içinde grup için benzersiz değerleri nereden bulacağım.

0
unique_A = FOREACH (GROUP A BY (a1, a2, a3)) { 
    limit_a = LIMIT A 1; 
    GENERATE FLATTEN(limit_a) AS (a1,a2,a3,a4); 
};