Apache Pig не может получить MIN (столбец), неожиданный символ

#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();