Напишите "Агрегатная функция" Pig UDF (прокрутите вниз до "Агрегатные функции"). Это определяемая пользователем функция, которая берет сумку и выводит скаляр. Таким образом, ваша UDF будет брать в сумку, определять, есть ли в ней более одного элемента, и соответствующим образом преобразовывать ее с помощью оператора if.
Я могу придумать способ сделать это без UDF, но это определенно неудобно. После вашего GROUP
используйте SPLIT
, чтобы разделить набор данных на два: один, в котором счетчик равен 1, и другой, в котором счетчик больше единицы:
SPLIT grouped INTO one IF COUNT(fruit) == 0, more IF COUNT(fruit) > 0;
Затем отдельно используйте FOREACH ... GENERATE
для каждого, чтобы преобразовать его:
one = FOREACH one GENERATE name, MAX(fruit); -- hack using MAX to get the item
more = FOREACH more GENERATE name, 'Multiple';
Наконец, объедините их обратно:
out = UNION one, more;
На самом деле я не нашел лучшего способа обработки одного и того же набора данных двумя разными способами на основе некоторых условных выражений, как вы хотите. Обычно я делаю какое-то разделение/рекомбинацию, как здесь. Я верю, что Свин будет умным и составит план, который не использует более 1 работы M/R.
Отказ от ответственности: в данный момент я не могу протестировать этот код, поэтому в нем могут быть ошибки.
Обновлять:
Присмотревшись повнимательнее, я вспомнил оператор bicond, и я думаю, что это будет работать здесь.
b = FOREACH a GENERATE name, (COUNT(fruit)==1 ? MAX(FRUIT) : 'Multiple');
person
Donald Miner
schedule
14.09.2011