Использование FILTER после FOREACH в Pig-Latin не удалось

Я новичок в Pig-Latin, и я обнаружил проблему с оператором FILTER. Посмотрите на пример:

Предположим, у нас есть файл данных (test.txt), содержимое которого:

1,2,3
2,3,4
3,4,5
4,5,6

Я хочу выбрать записи, у которых 1-е поле равно «3». Сценарий свиньи:

t = LOAD 'test.txt' USING PigStorage(',');
t1 = FOREACH t GENERATE $0 AS i0:chararray, $1 AS i1:chararray, $2 AS i2:chararray;
f1 = FILTER t1 BY i0 == '3';
DUMP f1

Задача выполняется хорошо, но на выходе ничего не получается. EXPLAIN f1 показывает:

#--------------------------------------------------
# Map Reduce Plan                                  
#--------------------------------------------------
MapReduce node scope-27
Map Plan
f1: Store(fakefile:org.apache.pig.builtin.PigStorage) - scope-26
|
|---f1: Filter[bag] - scope-22
    |   |
    |   Equal To[boolean] - scope-25
    |   |
    |   |---Project[chararray][0] - scope-23
    |   |
    |   |---Constant(3) - scope-24
    |
    |---t1: New For Each(false,false,false)[bag] - scope-21
        |   |
        |   Project[bytearray][0] - scope-15
        |   |
        |   Project[bytearray][1] - scope-17
        |   |
        |   Project[bytearray][2] - scope-19
        |
        |---t: Load(file:///Users/woody/test.txt:PigStorage(',')) - scope-14--------
Global sort: false
----------------

Однако, если я изменю две строки головы на:

t1 = LOAD 'test.txt' USING PigStorage(',') AS (i0:chararray, i1:chararray, i2:chararray)

(т.е. назначить схему в операторе LOAD)

Задача работает хорошо и результат тоже правильный. В этом случае EXPLAIN f1 показывает:

#--------------------------------------------------
# Map Reduce Plan                                  
#--------------------------------------------------
MapReduce node scope-33
Map Plan
f1: Store(fakefile:org.apache.pig.builtin.PigStorage) - scope-32
|
|---f1: Filter[bag] - scope-28
    |   |
    |   Equal To[boolean] - scope-31
    |   |
    |   |---Project[chararray][0] - scope-29
    |   |
    |   |---Constant(3) - scope-30
    |
    |---t1: New For Each(false,false,false)[bag] - scope-27
        |   |
        |   Cast[chararray] - scope-19
        |   |
        |   |---Project[bytearray][0] - scope-18
        |   |
        |   Cast[chararray] - scope-22
        |   |
        |   |---Project[bytearray][1] - scope-21
        |   |
        |   Cast[chararray] - scope-25
        |   |
        |   |---Project[bytearray][2] - scope-24
        |
        |---t1: Load(file:///Users/woody/test.txt:PigStorage(',')) - scope-17--------
Global sort: false
----------------

Это свиной жук? или есть хороший способ избежать этого?

pig --version на моем компьютере:

Apache Pig version 0.9.2 (r1232772)
compiled Jan 18 2012, 07:57:19

person Woody Wang    schedule 15.03.2012    source источник
comment
Это может быть незрелым, но я LOL'd.   -  person Vladislav Zorov    schedule 15.03.2012
comment
Что-то мешает вам сделать со вторым маршрутом и назначить схему в операторе LOAD с AS? Это кажется не только жизнеспособным решением, но и более эффективным кодированием.   -  person c.gutierrez    schedule 04.11.2013


Ответы (3)


Интересно, что это известная проблема, которая считается «не исправимой», так что на самом деле это не ошибка. это странное поведение, и, похоже, оно объясняет некоторую нерешительность, с которой я сталкивался в прошлом в отношении использования функции ФИЛЬТР.

следующее похоже и было закрыто с пометкой «не будет исправлено» в потоке комментариев: https://issues.apache.org/jira/browse/PIG-1341

во время загрузки действительно есть тонкости приведения, и это может помочь другим: http://ofps.oreilly.com/titles/9781449302641/data_model.html#type_strength

предыдущий ответ точен - я подтвердил, что он возвращает ожидаемый результат.

это может побудить меня явно бросить больше в будущем - отличный вопрос и ответ. извините, что ничего не добавил ... но подумал, что по теме достаточно, чтобы опубликовать.

person dave campbell    schedule 15.03.2012

Я знаю, что в GENERATE это дает тип данных, но не выполняет реальное приведение:

GENERATE $0 AS i0:chararray

Вам нужно разыграть его вручную:

t1 = FOREACH t GENERATE (chararray) $0 AS i0, (chararray) $1 AS i1, (chararray) $2 AS i2;

Это противоречит интуиции и, вероятно, является ошибкой.

person Romain    schedule 15.03.2012
comment
Просто в назидание другим пользователям: это не трюк. Это стандартный оператор приведения в стиле Java. - person WattsInABox; 13.03.2015

Это должно работать:

t = ЗАГРУЗИТЬ 'test.txt', ИСПОЛЬЗУЯ PigStorage(',') AS (i0:int, i1:int, i2:int);

t = ФИЛЬТР t BY i0 == 3;

ОТВАЛ т;

person user3933032    schedule 12.08.2014