2012-07-03 22 views
5

estoy usando PIG para generar grupos de tuplas de la siguiente manera:PIG: Obtener todas las tuplas de una bolsa agrupados

a1, b1 
a1, b2 
a1, b3 
... 

-> 

a1, [b1, b2, b3] 
... 

Esto es fácil y trabajo. Pero mi problema es conseguir lo siguiente: En los grupos obtenidos, me gustaría generar un conjunto de todas las tuplas de la bolsa del grupo:

a1, [b1, b2, b3] 

-> 

b1,b2 
b1,b3 
b2,b3 

esto sería fácil si pudiera nido "foreach" y en primer lugar iterate sobre cada grupo y luego sobre su bolsa.

Supongo que estoy malinterpretando el concepto y agradeceré su explicación.

Gracias.

Respuesta

15

Parece que necesita un producto cartesiano entre la bolsa y ella misma. Para hacer esto, necesita usar FLATTEN (bolsa) dos veces.

Código:

inpt = load '.../group.txt' using PigStorage(',') as (id, val); 
grp = group inpt by (id); 
id_grp = foreach grp generate group as id, inpt.val as value_bag; 
result = foreach id_grp generate id, FLATTEN(value_bag) as v1, FLATTEN(value_bag) as v2; 
dump result; 

Tenga en cuenta que las grandes bolsas producirán una gran cantidad de filas. Para evitarlo se puede utilizar TOP (...) antes de FLATTEN:

inpt = load '....group.txt' using PigStorage(',') as (id, val); 
grp = group inpt by (id); 
id_grp = foreach grp generate group as id, inpt.val as values; 
result = foreach id_grp { 
    limited_bag = TOP(50, 0, values); -- all sorts of filtering could be done here 
    generate id, FLATTEN(limited_bag) as v1, FLATTEN(limited_bag) as v2; 
}; 
dump result; 

Para su salida específico que podría utilizar algún tipo de filtrado antes de FLATTEN:

inpt = load '..../group.txt' as (id, val); 
grp = group inpt by (id); 
id_grp = foreach grp generate group as id, inpt.val as values; 
result = foreach id_grp { 
    l = filter values by val == 'b1' or val == 'b2'; 
    generate id, FLATTEN(l) as v1, FLATTEN(values) as v2; 
}; 
result = filter result by v1 != v2; 

espero que ayude.

Saludos

4

también es relevante este UnorderedPairs función de la biblioteca DataFu UDF. Se genera pares de todos los artículos en una bolsa (en su caso su bolsa agrupado)

+0

Laurens es correcto. Esta UDF hace exactamente lo que necesita y también es mucho más eficiente que una solución pura basada en cerdo que utiliza un producto cartesiano. Por cierto, la URL ha cambiado: [UnorderedPairs] (http://datafu.incubator.apache.org/docs/datafu/1.2.0/datafu/pig/bags/UnorderedPairs.html) – matterhayes

1

Puede utilizar la instrucción GROUP ALL cerdo para generar

A = -- Some bag 
B = -- Another bag 

groupedB = group B ALL; 
result = foreach A GENERATE 
    TOTUPLE(*), groupedB.$1; 

-- Will generate 
((a1), {(b1, b2, b3)}) 
((a2), {(b1, b2, b3)}) 
((a3), {(b1, b2, b3)}) 
... 
Cuestiones relacionadas