2016-01-19 3 views
0

Моя проблема в общем смысле заключается в том, что я хотел бы сгруппировать свои данные и затем подсчитать значения uniq для поля. В частности, для данных, приведенных ниже, я хочу группировать по «категории» и «год», а затем подсчитывать значения uniq для «food».Подсчитайте различные значения в группе с помощью свиней

category,id,mydate,mystore,food  
catA,myid_1,2014-03-11 13:13:13,store1,apple 
catA,myid_2,2014-03-11 12:12:12,store1,milk 
catA,myid_3,2014-08-11 10:13:13,store1,apple 
catA,myid_4,2014-09-11 09:12:12,store1,milk 
catA,myid_5,2015-09-01 10:10:10,store1,milk 
catB,myid_6,2014-03-12 03:03:03,store2,milk 
catB,myid_7,2014-03-12 05:55:55,store2,apple 

Это, насколько я могу получить, что просто выбирая значения и используя некоторые из аккуратных функций даты свинью:

a = load '$input' using PigStorage(',') as (category:chararray,id:chararray,mydate:chararray,mystore:chararray,food:chararray); 
b = foreach a generate category, id, ToDate(mydate,'yyyy-MM-dd HH:mm:ss') as myDt:DateTime, mystore,food; 


c = foreach b generate category, GetYear(myDt) as year:int, mystore,food;  
dump c; 

Выход из алиаса «C» является:

(catA,2014,store1,apple) 
(catA,2014,store1,milk) 
(catA,2014,store1,apple) 
(catA,2014,store1,milk) 
(catA,2015,store1,milk) 
(catB,2014,store2,milk) 
(catB,2014,store2,apple) 

Я хочу, чтобы в конце концов:

catA, 2014, {(apple, 2), (milk, 2)} 
catA, 2015, {(milk, 1)} 
catB, 2014, {(apple, 1), (milk, 1)} 

Я видел пример вычисления значений, но группировка по категориям и году меня отключает.

ответ

0

Вход:

категория, идентификатор, MyDate, MyStore, питание

catA,myid_1,2014-03-11 13:13:13,store1,apple 
catA,myid_2,2014-03-11 12:12:12,store1,milk 
catA,myid_3,2014-08-11 10:13:13,store1,apple 
catA,myid_4,2014-09-11 09:12:12,store1,milk 
catA,myid_5,2015-09-01 10:10:10,store1,milk 
catB,myid_6,2014-03-12 03:03:03,store2,milk 
catB,myid_7,2014-03-12 05:55:55,store2,apple 

Да, Вы можете использовать вложенную FOREACH после группировки В этой вложенной FOREACH вы можете применить Distinct для пищевых продуктов, а затем вам может считать это.

Код ниже поможет вам

Pig Сценарий:

list = LOAD 'user/cloudera/apple.txt' USING PigStorage(',') AS(category:chararray,id:chararray,mydate:chararray,my_store:chararray,food:chararray); 

list_each = FOREACH list GENERATE category,SUBSTRING(mydate,0,4) as my_year, my_store, food; 

list_grp = GROUP list_each BY (category,my_year); 

list_nested_each = FOREACH list_grp 

          { 
           list_inner_each = FOREACH list_each GENERATE food; 
           list_inner_dist = DISTINCT list_inner_each; 

          GENERATE flatten(group) as (catgeory,my_year), COUNT(list_inner_dist) as no_of_uniq_foods; 

          }; 

dump list_nested_each; 

Выход:

(catA,2014,2) 
(catA,2015,1) 
(catB,2014,2) 
0

прилагая к коду в вопросе:

d = group c by (category, year, food); 
e = foreach d generate FLATTEN(group), COUNT(c) as count; 

будет производить:

(catA,2014,milk,2) 
(catA,2014,apple,2) 
(catA,2015,milk,1) 
(catB,2014,milk,1) 
(catB,2014,apple,1) 

Ключ к группе 'пища', а также. Интересно. Любое другое понимание приветствуется.