Использование FILTER после FOREACH в Pig-Latin не удалось - PullRequest
2 голосов
/ 15 марта 2012

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

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

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

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

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
----------------

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

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 - версия на моем компьютере:

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

Ответы [ 3 ]

2 голосов
/ 15 марта 2012

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

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

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

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

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

1 голос
/ 15 марта 2012

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

GENERATE $0 AS i0:chararray

Вам необходимо привести его вручную:

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

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

0 голосов
/ 12 августа 2014

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

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

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

DUMP т;

...