Свинья udf на фильтр

У меня есть пример использования, в котором мне нужно взять дату месяца, чтобы вернуть последнюю дату предыдущего месяца.

Ex: input:20150331 output:20150228

Я буду использовать последнюю дату этого предыдущего месяца, чтобы отфильтровать ежедневный раздел (в скрипте свиньи).

B = filter A by daily_partition == GetPrevMonth(20150331);

Я создал UDF (GetPrevMonth), который принимает дату и возвращает последнюю дату предыдущего месяца, но не может использовать ее в фильтре.

ERROR:Could not infer the matching function for GetPrevMonth as multiple or none of them fit. Please use an explicit cast.

Мой udf принимает кортеж в качестве входных данных. В Google говорится, что UDF нельзя применять к фильтрам. Есть ли обходной путь? или я где-то ошибаюсь?

UDF:public class GetPrevMonth extends EvalFunc<Integer> {

    public Integer exec(Tuple input) throws IOException {
        String getdate = (String) input.get(0);
        if (getdate != null){
        try{
            //LOGIC to return prev month date
        }

Нужна помощь. Заранее спасибо.


person Pratik    schedule 28.07.2015    source источник
comment
Вам следует принять ответ Бальдуза, если вы не чувствуете, что он вас не устраивает (мне это кажется правильным)   -  person Eyal    schedule 19.05.2016


Ответы (1)


Вы можете вызвать UDF в FILTER, но вы передаете номер функции, ожидая, что она получит String (chararray внутри Pig):

String getdate = (String) input.get(0);

Простым решением было бы преобразовать его в chararray при вызове UDF:

B = filter A by daily_partition == GetPrevMonth((chararray)20150331);

Как правило, когда вы видите ошибку типа Could not infer the matching function for X as multiple or none of them fit, в 99% случаев причина в том, что значения, которые вы пытаетесь передать в UDF, неверны.

И последнее, даже если в этом нет необходимости, в будущем вы, возможно, захотите написать чистый FILTER UDF. В этом случае вместо наследования от EvalFunc вам нужно наследовать от FilterFunc и вернуть значение Boolean:

public class IsPrevMonth extends FilterFunc {
    @Override
    public Boolean exec(Tuple input) throws IOException {
        try {
            String getdate = (String) input.get(0);
            if (getdate != null){   
                //LOGIC to retrieve prevMonthDate

                if (getdate.equals(prevMonthDate)) {
                    return true;
                } else {
                    return false;   
                }
            } else {
                return false;
            }
        } catch (ExecException ee) {
            throw ee;
        }
    }
} 
person Balduz    schedule 28.07.2015