#hadoop #apache-pig #min
#hadoop #apache-pig #min
Вопрос:
Я изо всех сил пытаюсь понять, как использовать функцию MIN () в этом случае. У меня есть следующий сценарий Pig:
A = LOAD '/home/mqp/Documents/p1/data/test_customers.csv' USING CSVExcelStorage (',') AS
(custid:int, name:chararray, age:int, gender:chararray, country:int, salary:float);
B = LOAD '/home/mqp/Documents/p1/data/test_transactions.csv' USING CSVExcelStorage (',') AS (transid:int, custid:int, ttotal:float, items:int, tdesc:chararray);
C = JOIN B BY custid, A BY custid USING 'replicated';
D = GROUP C BY $1;
DESCRIBE D;
out = FOREACH D {
allids = FOREACH C GENERATE B::custid;
singleids = DISTINCT allids;
allnames = FOREACH C GENERATE name;
singlenames = DISTINCT allnames;
allsal= FOREACH C GENERATE salary;
singlesal = DISTINCT allsal;
alltotals = FOREACH C GENERATE B::ttotal as bt;
mintotals = FOREACH alltotals GENERATE MIN(alltotals.bt);
transtotal = FOREACH C GENERATE ttotal;
GENERATE flatten(singleids), flatten(singlenames), flatten(singlesal), COUNT(C), SUM(transtotal), flatten(mintotals);
};
STORE out INTO '/home/mqp/Documents/p1/pig_test' USING CSVExcelStorage();
Я перепробовал бесчисленное множество различных методов, чтобы заставить функцию MIN() работать здесь, но безрезультатно. Я пробовал группировать по всем, используя разные индексы и т.д. Я действительно не понимаю, что мне нужно делать.
Я получаю ошибки «неожиданный символ в foo или рядом с ним» и «недопустимая скалярная проекция»
Комментарии:
1. работает ли этот скрипт без использования функции MIN?
Ответ №1:
Вы должны использовать MIN
функцию в основном GENERATE
блоке, а не во вложенном FOREACH
, как у вас есть в настоящее время. Это связано с тем, что функция MIN ожидает пакет значений, например COUNT
, и SUM
которые вы правильно использовали.
Вот возможная версия скрипта, который должен работать (добавлены некоторые комментарии к изменениям, которые я внес в ваш исходный сценарий для ясности):
A = LOAD 'test_customers.csv' USING CSVExcelStorage (',') AS (
custid:int,
name:chararray,
age:int,
gender:chararray,
country:int,
salary:float
);
B = LOAD 'test_transactions.csv' USING CSVExcelStorage (',') AS (
transid:int,
custid:int,
ttotal:float,
items:int,
tdesc:chararray
);
C = JOIN B BY custid, A BY custid USING 'replicated';
-- Removed the DESCRIBE and used field name in GROUP BY for clarity.
D = GROUP C BY B::custid;
out = FOREACH D {
-- Removed DISTINCT custid
-- Because we grouped by this field, we can just generate group
-- Consider adding name and salary to the GROUP BY if you
-- expect these to be the same for each custid.
allnames = FOREACH C GENERATE name;
singlenames = DISTINCT allnames;
allsal= FOREACH C GENERATE salary;
singlesal = DISTINCT allsal;
alltotals = FOREACH C GENERATE B::ttotal as bt;
-- transtotals was effectively the same as alltotals
GENERATE
group,
FLATTEN(singlenames),
FLATTEN(singlesal),
COUNT(C),
SUM(alltotals.bt),
MIN(alltotals.bt);
}
STORE out INTO 'pig_test' USING CSVExcelStorage();