Spec-Zone.ru › Apache Pig 0.16

Основы Pig Latin

  • Конвенции
  • Зарезервированные ключевые слова
  • Чувствительность к регистру
  • Типы данных и многое другое
    • Идентификаторы
    • Взаимосвязи, наборы, кортежи, поля
    • Типы данных
    • Null и Pig Latin
    • Константы
    • Выражения
    • Схемы
  • Арифметические операторы и многое другое
    • Арифметические операторы
    • Булевы операторы
    • Операторы приведения типов
    • Операторы сравнения
    • Операторы построения типов
    • Операторы разыменования
    • Оператор устранения неоднозначности
    • Оператор сплющивания
    • Операторы null
    • Операторы знака
  • Операторы отношений
    • ASSERT
    • COGROUP
    • CROSS
    • CUBE
    • DEFINE
    • DISTINCT
    • FILTER
    • FOREACH
    • GROUP
    • IMPORT
    • JOIN (внутреннее)
    • JOIN (внешнее)
    • LIMIT
    • LOAD
    • MAPREDUCE
    • ORDER BY
    • RANK
    • SAMPLE
    • SPLIT
    • STORE
    • STREAM
    • UNION
  • Заявления UDF
    • DEFINE (UDFs, потоковая обработка)
    • REGISTER (jar/скрипт)
    • REGISTER (артефакт)

Конвенции

Здесь описаны конвенции синтаксиса и примеров кода в Руководстве по Pig Latin.

Конвенция

Описание

Пример

( )

Скобки содержат один или несколько элементов.

Скобки также используются для указания типа данных кортежа.

Несколько элементов:

(1, abc, (2,4,6) )

[ ]

Прямые скобки содержат один или несколько необязательных элементов.

Прямые скобки также используются для указания типа данных карты. В этом случае <> используется для обозначения необязательных элементов.

Необязательные элементы:

[INNER | OUTER]

{ }

Фигурные скобки содержат два или более элементов, один из которых обязателен.

Фигурные скобки также используются для указания типа данных набора. В этом случае <> используется для обозначения обязательных элементов.

Два элемента, один обязателен:

{ block | nested_block }

…

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

Выражение синтаксиса Pig Latin:

cat path [path …]

ВЕРХНИЙ РЕГИСТР

нижний регистр

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

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

(Эти соглашения не строго соблюдаются во всех примерах.)

См. Чувствительность к регистру

Выражение Pig Latin:

a = LOAD 'data' AS (f1:int);

  • LOAD, AS - ключевые слова Pig

  • a, f1 - псевдонимы, которые вы предоставляете

  • 'data' - источник данных, который вы предоставляете

Зарезервированные ключевые слова

Здесь перечислены зарезервированные ключевые слова Pig.

-- A

assert, and, any, all, arrange, as, asc, AVG

-- B

bag, BinStorage, by, bytearray, BIGINTEGER, BIGDECIMAL

-- C

cache, CASE, cat, cd, chararray, cogroup, CONCAT, copyFromLocal, copyToLocal, COUNT, cp, cross

-- D

datetime, %declare, %default, define, dense, desc, describe, DIFF, distinct, double, du, dump

-- E

e, E, eval, exec, explain

... (rest of the table) ...

Чувствительность к регистру

Имена (псевдонимы) отношений и полей чувствительны к регистру. Имена функций Pig Latin чувствительны к регистру. Имена параметров (см. Замена параметров) и все другие ключевые слова Pig Latin (см. Зарезервированные ключевые слова) нечувствительны к регистру.

В примере ниже обратите внимание на следующее:

  • Имена (псевдонимы) отношений A, B и C чувствительны к регистру.

  • Имена (псевдонимы) полей f1, f2 и f3 чувствительны к регистру.

  • Имена функций PigStorage и COUNT чувствительны к регистру.

  • Ключевые слова LOAD, USING, AS, GROUP, BY, FOREACH, GENERATE и DUMP нечувствительны к регистру. Их также можно записать как load, using, as, group, by и т.д.

  • В операторе FOREACH поле в отношении B ссылается с помощью позиционного обозначения ($0).

grunt> A = LOAD 'data' USING PigStorage() AS (f1:int, f2:int, f3:int);
grunt> B = GROUP A BY f1;
grunt> C = FOREACH B GENERATE COUNT ($0);
grunt> DUMP C;

Типы данных и многое другое

Идентификаторы

Идентификаторы включают имена отношений (псевдонимов), полей, переменных и так далее. В Pig идентификаторы начинаются с буквы и могут содержать любое количество букв, цифр или символов подчеркивания.

Допустимые идентификаторы:

A
A123
abc_123_BeX_

Недопустимые идентификаторы:

_A123
abc_$
A!B

Отношения, Мешки, Кортежи, Поля

Операторные выражения Pig Latin работают с отношениями. Отношение может быть определено следующим образом:

  • Отношение является мешком (точнее, внешним мешком).

  • Мешок — это коллекция кортежей.

  • Кортеж — упорядоченный набор полей.

  • Поле — фрагмент данных.

Отношение Pig — это мешок кортежей. Отношение Pig аналогично таблице в реляционной базе данных, где кортежи в мешке соответствуют строкам в таблице. Однако, в отличие от реляционной таблицы, отношения Pig не требуют, чтобы каждый кортеж содержал одинаковое количество полей или чтобы поля в одном и том же положении (столбце) имели одинаковый тип.

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

Ссылка на Отношения

К отношениям обращаются по имени (или псевдониму). Имена присваиваются вами в качестве части операторного выражения Pig Latin. В этом примере имя (псевдоним) отношения — A.

A = LOAD 'student' USING PigStorage() AS (name:chararray, age:int, gpa:float);
DUMP A;
(John,18,4.0F)
(Mary,19,3.8F)
(Bill,20,3.9F)
(Joe,18,3.8F)

Вы можете назначить псевдоним другому псевдониму. Новый псевдоним может использоваться вместо исходного псевдонима для ссылки на исходное отношение.

  A = LOAD 'student' USING PigStorage() AS (name:chararray, age:int, gpa:float);
  B = A;
  DUMP B;
  

Ссылка на Поля

К полям обращаются с помощью позиционного обозначения или по имени (псевдониму).

  • Позиционное обозначение генерируется системой. Позиционное обозначение обозначается знаком доллара ($) и начинается с нуля (0); например, $0, $1, $2.

  • Имена присваиваются вами, используя схемы (или, в случае оператора GROUP и некоторых функций, системой). Вы можете использовать любое имя, которое не является ключевым словом Pig (см. Идентификаторы для примеров допустимых имен).

Учитывая отношение A выше, три поля выделены в этой таблице.

Первое поле

Второе поле

Третье поле

Тип данных

chararray

int

float

Позиционное обозначение (генерируется системой)

$0

$1

$2

Возможные имена (присваиваются вами с использованием схемы)

имя

возраст

gpa

Значение поля (для первого кортежа)

John

18

4.0

Как показано в этом примере, при назначении имен полям (используя предложение схемы AS) вы по-прежнему можете ссылаться на поля с использованием позиционного обозначения. Однако для целей отладки и простоты понимания лучше использовать имена полей.

A = LOAD 'student' USING PigStorage() AS (name:chararray, age:int, gpa:float);
X = FOREACH A GENERATE name,$2;
DUMP X;
(John,4.0F)
(Mary,3.8F)
(Bill,3.9F)
(Joe,3.8F)

В этом примере генерируется ошибка, потому что запрашиваемый столбец ($3) находится за пределами объявленной схемы (позиционное обозначение начинается с $0). Обратите внимание, что ошибка обнаруживается до выполнения операторных выражений.

A = LOAD 'data' AS (f1:int,f2:int,f3:int);
B = FOREACH A GENERATE $3;
DUMP B;
2009-01-21 23:03:46,715 [main] ERROR org.apache.pig.tools.grunt.GruntParser - java.io.IOException: 
Out of bound access. Trying to access non-existent  : 3. Schema {f1: bytearray,f2: bytearray,f3: bytearray} has 3 column(s). 
etc ... 

Ссылка на поля, являющиеся сложными типами данных

Как отмечалось, поля в кортеже могут быть любого типа данных, включая сложные типы данных: мешки, кортежи и карты.

  • Используйте схемы для сложных типов данных для именования полей, которые являются сложными типами данных.

  • Используйте операторы разыменования для ссылки и работы с полями, которые являются сложными типами данных.

В этом примере файл данных содержит кортежи. Используется схема для сложных типов данных (в данном случае кортежей) для загрузки данных. Затем операторы разыменования (точка в t1.t1a и t2.$0) используются для доступа к полям в кортежах. Обратите внимание, что при назначении имен полям вы по-прежнему можете ссылаться на эти поля с использованием позиционного обозначения.

cat data;
(3,8,9) (4,5,6)
(1,4,7) (3,7,5)
(2,5,8) (9,5,8)

A = LOAD 'data' AS (t1:tuple(t1a:int, t1b:int,t1c:int),t2:tuple(t2a:int,t2b:int,t2c:int));

DUMP A;
((3,8,9),(4,5,6))
((1,4,7),(3,7,5))
((2,5,8),(9,5,8))

X = FOREACH A GENERATE t1.t1a,t2.$0;

DUMP X;
(3,4)
(1,3)
(2,9)

Типы данных

Простые и Сложные

Простые типы

Описание

Пример

int

Целое 32-битное со знаком

10

long

Целое 64-битное со знаком

Данные: 10L или 10l

Вывод: 10L

float

32-битное число с плавающей точкой

Данные: 10.5F или 10.5f или 10.5e2f или 10.5E2F

Вывод: 10.5F или 1050.0F

double

64-битное число с плавающей точкой

Данные: 10.5 или 10.5e2 или 10.5E2

Вывод: 10.5 или 1050.0

chararray

Массив символов (строка) в формате Unicode UTF-8

hello world

bytearray

Массив байтов (blob)

boolean

логический

true/false (регистр не важен)

datetime

datetime

1970-01-01T00:00:00.000+00:00

biginteger

Java BigInteger

200000000000

bigdecimal

Java BigDecimal

33.456783321323441233442

Сложные типы

tuple

Упорядоченный набор полей.

(19,2)

bag

Коллекция кортежей.

{(19,2), (18,1)}

map

Набор пар ключ-значение.

[open#apache]

Обратите внимание на следующие общие наблюдения за типами данных:

  • Используйте схемы для присвоения типов полям. Если вы не присваиваете типы, поля по умолчанию имеют тип bytearray, и неявные преобразования применяются к данным в зависимости от контекста, в котором используются эти данные. Например, в отношении B f1 преобразуется в целое число, потому что 5 — целое число. В отношении C f1 и f2 преобразуются в double, поскольку мы не знаем тип ни f1, ни f2.

    A = LOAD 'data' AS (f1,f2,f3);
    B = FOREACH A GENERATE f1 + 5;
    C = FOREACH A generate f1 + f2;
    
  • Если схема определена как часть операторного выражения загрузки, функция загрузки попытается применить схему. Если данные не соответствуют схеме, загрузчик сгенерирует значение null или ошибку.

    A = LOAD 'data' AS (name:chararray, age:int, gpa:float);
    
  • Если явное преобразование не поддерживается, произойдет ошибка. Например, вы не можете преобразовать chararray в int.

    A = LOAD 'data' AS (name:chararray, age:int, gpa:float);
    B = FOREACH A GENERATE (int)name;
    
    This will cause an error …
  • Если Pig не может разрешить несовместимые типы с помощью неявных преобразований, произойдет ошибка. Например, вы не можете сложить chararray и float (см. таблицу типов для сложения и вычитания).

    A = LOAD 'data' AS (name:chararray, age:int, gpa:float);
    B = FOREACH A GENERATE name + gpa;
    
    This will cause an error …

Все типы данных имеют соответствующие схемы.

Кортеж

Кортеж — упорядоченный набор полей.

Синтаксис

( поле [, поле …] )

Термины

( )

Кортеж заключен в скобки ( ).

поле

Фрагмент данных. Поле может быть любого типа данных (включая кортеж и мешок).

Использование

Вы можете рассматривать кортеж как строку с одним или несколькими полями, где каждое поле может быть любого типа, и любое поле может или не может иметь данные. Если поле не содержит данных, происходит следующее:

  • В операторном выражении загрузки загрузчик вставит null в кортеж. Фактическое значение, которое подставляется вместо null, зависит от загрузчика; например, PigStorage подставляет пустое поле вместо null.

  • В операторном выражении, отличном от загрузки, если запрашиваемое поле отсутствует в кортеже, Pig вставит null.

См. также схемы кортежей.

Пример

В этом примере кортеж содержит три поля.

(John,18,4.0F)

Мешок

Мешок — это коллекция кортежей.

Синтаксис: Внутренний мешок

{ кортеж [, кортеж …] }

Термины

{ }

Внутренний мешок заключен в фигурные скобки { }.

кортеж

Кортеж.

Использование

Обратите внимание на следующее в отношении мешков:

  • Мешок может содержать дублированные кортежи.

  • Мешок может содержать кортежи с различным количеством полей. Однако если Pig пытается получить доступ к полю, которого не существует, вместо него подставляется значение null.

  • Мешок может содержать кортежи с полями различных типов данных. Однако для эффективной обработки мешков Pig схемы кортежей в этих мешках должны быть одинаковыми. Например, если половина кортежей содержит поля chararray, а другая половина — float, только половина кортежей будет участвовать в вычислениях, поскольку поля chararray преобразуются в null.

    Мешки имеют две формы: внешний мешок (или отношение) и внутренний мешок.

См. также схемы мешков.

Пример: Внешний мешок

В этом примере A — это отношение или мешок кортежей. Вы можете рассматривать этот мешок как внешний мешок.

A = LOAD 'data' as (f1:int, f2:int, f3:int);
DUMP A;
(1,2,3)
(4,2,1)
(8,3,4)
(4,3,3)
Пример: Внутренний пакет

Предположим, что мы сгруппируем отношение A по первому полю, чтобы получить отношение X.

В этом примере X — это отношение или пакет кортежей. Кортежи в отношении X имеют два поля. Первое поле имеет тип int. Второе поле имеет тип пакет; вы можете рассматривать этот пакет как внутренний пакет.

X = GROUP A BY f1;
DUMP X;
(1,{(1,2,3)})
(4,{(4,2,1),(4,3,3)})
(8,{(8,3,4)})

Словарь

Словарь — это набор пар «ключ/значение».

Синтаксис (<> означает необязательно)

[ ключ#значение <, ключ#значение …> ]

Термины

[ ]

Словари заключены в прямые скобки [ ].

#

Пары «ключ-значение» разделены знаком решётки #.

ключ

Должен быть типом данных chararray. Должен иметь уникальное значение.

значение

Любой тип данных (по умолчанию — bytearray).

Использование

Значения ключей в отношении должны быть уникальными.

См. также схемы словарей.

Пример

В этом примере словарь содержит две пары «ключ-значение».

[name#John,phone#5551212]

Значения NULL и Pig Latin

В Pig Latin значения NULL реализованы с использованием определения SQL значения NULL как неизвестного или несуществующего. Значения NULL могут естественным образом встречаться в данных или могут быть результатом операции.

Значения NULL, операторы и функции

Операторы и функции Pig Latin взаимодействуют со значениями NULL, как показано в этой таблице.

Оператор

Взаимодействие

Операторы сравнения:

==, !=

>, <

>=, <=

Если какой-либо из подвыражений равен NULL, результат равен NULL.

Оператор сравнения:

matches

Если строка, с которой производится сравнение, или строка, определяющая соответствие, равна NULL, результат равен NULL.

Арифметические операторы:

+, -, *, /

% modulo

? : bincond

CASE : case

Если какой-либо из подвыражений равен NULL, результат выражения равен NULL.

Оператор NULL:

is null

Если тестируемое значение равно NULL, возвращает true; в противном случае возвращает false (см. Операторы NULL).

Оператор NULL:

is not null

Если тестируемое значение не равно NULL, возвращает true; в противном случае возвращает false (см. Операторы NULL).

Операторы разыменования:

кортеж (.) или словарь (#)

Если разыменовываемый кортеж или словарь равен NULL, возвращается NULL.

Операторы:

COGROUP, GROUP, JOIN

Эти операторы обрабатывают значения NULL по-разному (см. примеры ниже).

Функция:

COUNT_STAR

Эта функция подсчитывает все значения, включая значения NULL.

Оператор приведения типа

Приведение значения NULL из одного типа в другой приводит к значению NULL.

Функции:

AVG, MIN, MAX, SUM, COUNT

Эти функции игнорируют значения NULL.

Функция:

CONCAT

Если какое-либо из подвыражений равно NULL, результирующее выражение равно NULL.

Функция:

SIZE

Если проверяемый объект равен NULL, возвращается NULL.

Для булевых подвыражений обратите внимание на результаты, когда значения NULL используются с этими операторами:

  • Оператор FILTER — если выражение фильтра приводит к значению NULL, фильтр не пропускает их (если X равно NULL, !X также равно NULL, и фильтр отклонит оба).

  • Оператор bincond — если булевое подвыражение приводит к значению NULL, результирующее выражение равно NULL (см. взаимодействие выше для арифметических операторов).

Значения NULL и константы

Значения NULL могут использоваться в качестве константных выражений вместо выражений любого типа.

В этом примере проецируются a и NULL.

A = LOAD 'data' AS (a, b, c).
B = FOREACH A GENERATE a, null;

В этом примере внешнего соединения, если ключ соединения отсутствует в таблице, он заменяется на NULL.

A = LOAD 'student' AS (name: chararray, age: int, gpa: float);
B = LOAD 'votertab10k' AS (name: chararray, age: int, registration: chararray, donation: float);
C = COGROUP A BY name, B BY name;
D = FOREACH C GENERATE FLATTEN((IsEmpty(A) ? null : A)), FLATTEN((IsEmpty(B) ? null : B));

Как и любое другое выражение, константы NULL могут быть неявно или явно приведены к другому типу.

В этом примере a и NULL будут неявно приведены к типу double.

A = LOAD 'data' AS (a, b, c).
B = FOREACH A GENERATE a + null;

В этом примере a и NULL будут приведены к типу int, a неявно, а NULL явно.

A = LOAD 'data' AS (a, b, c).
B = FOREACH A GENERATE a + (int)null;

Операции, которые возвращают NULL

Как отмечалось, значения NULL могут быть результатом операции. Эти операции могут возвращать значения NULL:

  • Деление на ноль

  • Возвращаемые значения пользовательских функций (UDF)

  • Разыменование поля, которого не существует.

  • Разыменование ключа, которого нет в словаре. Например, применительно к словарю info, содержащему ['name#john', 'phone#5551212'], если пользователь пытается использовать info#address, возвращается NULL.

  • Обращение к полю, которого нет в кортеже.

Пример: Обращение к полю, которого нет в кортеже

В этом примере вставляются значения NULL, если поля не содержат данных.

cat data;
    2   3
4   
7   8   9

A = LOAD 'data' AS (f1:int,f2:int,f3:int)

DUMP A;
(,2,3)
(4,,)
(7,8,9)

B = FOREACH A GENERATE f1,f2;

DUMP B;
(,2)
(4,)
(7,8)

Значения NULL и функции загрузки

Как отмечалось, значения NULL могут естественным образом встречаться в данных. Если значения NULL присутствуют в данных, функция загрузки должна правильно их обрабатывать. Имейте в виду, что то, что считается значением NULL, зависит от конкретной функции загрузки; однако функция загрузки всегда должна сообщать значения NULL в Pig, создавая Java null.

Функции загрузки Pig Latin (например, PigStorage и TextLoader) генерируют значения NULL, когда данные отсутствуют. Например, пустые строки (chararrays) не загружаются; вместо этого они заменяются значениями NULL.

PigStorage — это функция загрузки по умолчанию для оператора LOAD. В этом примере используется оператор is not null для фильтрации имён с значениями NULL.

A = LOAD 'student' AS (name, age, gpa); 
B = FILTER A BY name is not null;

Значения NULL и операторы GROUP/COGROUP

При использовании оператора GROUP с одним отношением записи с ключом группы NULL группируются вместе.

A = load 'student' as (name:chararray, age:int, gpa:float);
dump A;
(joe,18,2.5)
(sam,,3.0)
(bob,,3.5)

X = group A by age;
dump X;
(18,{(joe,18,2.5)})
(,{(sam,,3.0),(bob,,3.5)})
   

При использовании оператора GROUP (COGROUP) с несколькими отношениями записи с ключом группы NULL из разных отношений считаются разными и группируются отдельно. В примере ниже обратите внимание, что в выводе есть два кортежа, соответствующие ключу группы NULL: один, содержащий кортежи из отношения A (но не отношения B), и один, содержащий кортежи из отношения B (но не отношения A).

A = load 'student' as (name:chararray, age:int, gpa:float);
B = load 'student' as (name:chararray, age:int, gpa:float);
dump B;
(joe,18,2.5)
(sam,,3.0)
(bob,,3.5)

X = cogroup A by age, B by age;
dump X;
(18,{(joe,18,2.5)},{(joe,18,2.5)})
(,{(sam,,3.0),(bob,,3.5)},{})
(,{},{(sam,,3.0),(bob,,3.5)})

Значения NULL и оператор JOIN

Оператор JOIN — при выполнении внутренних соединений — следует стандарту SQL и игнорирует (фильтрует) значения NULL. (См. также Убрать NULL перед соединением.)

A = load 'student' as (name:chararray, age:int, gpa:float);
B = load 'student' as (name:chararray, age:int, gpa:float);
dump B;
(joe,18,2.5)
(sam,,3.0)
(bob,,3.5)
  
X = join A by age, B by age;
dump X;
(joe,18,2.5,joe,18,2.5)

Константы

Pig предоставляет константные представления для всех типов данных, кроме bytearrays.

Пример константы

Примечания

Простые типы данных

int

19

long

19L

float

19.2F или 1.92e2f

double

19.2 или 1.92e2

chararray

'привет мир'

bytearray

Не применимо.

boolean

true/false

Регистронезависимые.

Сложные типы данных

кортеж

(19, 2, 1)

Константа в этом формате создаёт кортеж.

пакет

{ (19, 2), (1, 2) }

Константа в этом формате создаёт пакет.

словарь

[ 'name' # 'Иван', 'ext' # 5555 ]

Константа в этом формате создаёт словарь.

Обратите внимание на следующее:

  • В UTF-8 системах вы можете указывать строковые константы, состоящие из печатных символов ASCII, например, 'abc'; вы можете указывать управляющие символы, такие как '\t'; и вы можете указывать символ Unicode, начиная его с '\u', например, '\u0001' представляет Ctrl-A в шестнадцатеричном формате (см. Wikipedia ASCII, Unicode и UTF-8). Теоретически вы должны иметь возможность указывать константы, не являющиеся UTF-8, в системах, не поддерживающих UTF-8, но насколько нам известно, это не было проверено.

  • Для указания константы типа long необходимо добавить l или L к числу (например, 12345678L). Если l или L не указаны, но число слишком велико, чтобы поместиться в int, проблема будет обнаружена во время разбора, и обработка будет прекращена.

  • Любая числовая константа с десятичной точкой (например, 1,5) и/или показателем степени (например, 5e+1) обрабатывается как double, если она не заканчивается на f или F, в противном случае ей назначается тип float (например, 1,5f).

  • Нет встроенного типа константы для поля datetime. Вы можете использовать udf ToDate с константой chararray в качестве аргумента для создания значения datetime.

Определения типов данных для кортежей, пакетов и словарей применяются к константам:

  • Кортеж может содержать поля любого типа данных

  • Множество — это коллекция кортежей

  • Ключ карты должен быть chararray; значение карты может быть любого типа данных

Сложные константы (с значениями или без них) могут использоваться в тех же местах, что и скалярные константы; то есть, в операторах FILTER и GENERATE.

A = LOAD 'data' USING MyStorage() AS (T: tuple(name:chararray, age: int));
B = FILTER A BY T == ('john', 25);
D = FOREACH B GENERATE T.name, [25#5.6], {(1, 5, 18)};

Выражения

В Pig Latin выражения — это конструкции языка, используемые с операторами FILTER, FOREACH, GROUP и SPLIT, а также функциями eval.

Выражения записываются в стандартной математической инфиксной нотации и адаптированы к набору символов UTF-8. В зависимости от контекста выражения могут включать:

  • Любой тип данных Pig (простые и сложные типы данных)

  • Любой оператор Pig (арифметические, сравнения, null, boolean, обращение, знак и приведение типов)

  • Любую встроенную функцию Pig.

  • Любую пользовательскую функцию (UDF), написанную на Java.

В Pig Latin,

  • Арифметическое выражение может выглядеть так:

    X = GROUP A BY f2*f3;
    
  • Строковое выражение может выглядеть так, где a и b — оба chararray:

    X = FOREACH A GENERATE CONCAT(a,b);
    
  • Булево выражение может выглядеть так:

    X = FILTER A BY (f1==8) OR (NOT (f2+f3 > f1));
    

Выражения полей

Выражения полей представляют поле или оператор обращения к полю.

Выражения со звездочкой

Выражения со звездочкой ( * ) могут использоваться для представления всех полей кортежа. Это эквивалентно явному перечислению полей. В следующем примере определения B и C идентичны, и MyUDF вызывается с точно такими же аргументами в обоих случаях.

A = LOAD 'data' USING MyStorage() AS (name:chararray, age: int);
B = FOREACH A GENERATE *, MyUDF(name, age);
C = FOREACH A GENERATE name, age, MyUDF(*);
          

Распространённая ошибка при использовании выражения со звездочкой показана ниже. В этом примере программист действительно хочет подсчитать количество элементов в множестве во втором поле: COUNT($1).

G = GROUP A BY $0;
C = FOREACH G GENERATE COUNT(*)
          

Существуют некоторые ограничения на использование выражения со звездочкой, когда схема входных данных неизвестна (null):

  • Для GROUP/COGROUP вы не можете включить выражение со звездочкой в столбец GROUP BY.
  • Для ORDER BY, если у вас есть проекция со звездочкой в качестве столбца ORDER BY, вы не можете иметь другие столбцы ORDER BY в этом операторе.

Выражения проекции диапазона

Выражения проекции диапазона ( .. ) могут использоваться для проекции диапазона столбцов из входных данных. Например:

  • .. $x : проецирует столбцы с $0 до $x включительно
  • $x .. : проецирует столбцы до конца включительно
  • $x .. $y : проецирует столбцы до $y включительно

Если у входного отношения есть схема, вы можете ссылаться на столбцы по имени, а не по позиционному номеру. Вы также можете объединять имена и позиционные номера столбцов в выражении; например, «col1 .. $5» допустимо.

Выражения проекции диапазона могут использоваться во всех случаях, когда разрешено выражение со звездочкой ( * ).

Выражения проекции диапазона могут использоваться в следующих операторах: FOREACH, JOIN, GROUP, COGROUP и ORDER BY (также когда ORDER BY используется внутри вложенного блока FOREACH).

Вот несколько примеров:

..... 
grunt> F = foreach IN generate (int)col0, col1 .. col3; 
grunt> describe F; 
F: {col0: int,col1: bytearray,col2: bytearray,col3: bytearray} 
..... 
..... 
grunt> SORT = order IN by col2 .. col3, col0, col4 ..; 
..... 
..... 
J = join IN1 by $0 .. $3, IN2 by $0 .. $3; 
..... 
..... 
g = group l1 by b .. c; 
..... 

Существуют некоторые ограничения на использование формы проекции до конца выражения проекции диапазона (например, «x .. ») когда схема входных данных неизвестна (null):

  • Для GROUP/COGROUP форма проекции до конца выражения проекции диапазона недопустима.
  • Для ORDER BY форма проекции до конца выражения проекции диапазона поддерживается только в качестве последнего столбца сортировки.
    ..... 
    grunt> describe IN; 
    Schema for IN unknown. 
    
    /* This statement is supported */
    SORT = order IN by $2 .. $3, $6 ..; 
    
    /* This statement is NOT supported */ 
    SORT = order IN by $2 .. $3, $6 ..; 
    ..... 
    

Булевы выражения

Булевы выражения могут состоять из UDF, возвращающих булево значение, или булевых операторов (см. Булевы операторы).

Выражения кортежей

Выражения кортежей образуют подвыражения в кортежи. Выражение кортежа имеет вид (выражение [, выражение …]), где выражение — это общее выражение. Простейшее выражение кортежа — выражение со звездочкой, представляющее все поля.

Общие выражения

Общие выражения могут состоять из UDF и почти любого оператора. Так как Pig не считает boolean базовым типом, результат общего выражения не может быть булевым. Выражения полей — простейшие общие выражения.

Схемы

Схемы позволяют назначать имена полям и объявлять типы полей. Схемы являются необязательными, но мы рекомендуем использовать их всякий раз, когда это возможно; объявления типов приводят к лучшему контролю ошибок на стадии парсинга и более эффективному выполнению кода.

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

Схемы определяются с помощью операторов LOAD, STREAM и FOREACH с помощью предложения AS. Если вы определяете схему с помощью оператора LOAD, то именно функция загрузки обеспечивает соответствие схеме (см. LOAD и Пользовательские функции для получения дополнительной информации).

Обработка известных схем

Обратите внимание на следующее:

  • Вы можете определить схему, которая включает как имя поля, так и тип поля.
  • Вы можете определить схему, которая включает только имя поля; в этом случае тип поля по умолчанию — bytearray.
  • Вы можете выбрать не определять схему; в этом случае поле не имеет имени, а тип поля по умолчанию — bytearray.

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

Если вы назначаете тип полю, вы можете впоследствии изменить тип с помощью операторов приведения типов. Если вы не назначаете тип полю, поле по умолчанию имеет тип bytearray; вы можете изменить тип по умолчанию с помощью операторов приведения типов.

Обработка неизвестных схем

Обратите внимание на следующее:

  • При объединении/COGROUP/CROSS нескольких отношений, если какое-либо отношение имеет неизвестную схему (или схему по умолчанию, также называемую нулевой схемой), схема для результирующего отношения будет нулевой.
  • Если вы применяете FLATTEN к множеству с пустой внутренней схемой, схема для результирующего отношения будет нулевой.
  • Если вы объединяете два отношения с несовместимой схемой, схема для результирующего отношения будет нулевой.
  • Если схема нулевая, Pig рассматривает все поля как bytearray (внутренне Pig определит реальный тип полей динамически)

Смотрите примеры ниже. Если тип данных поля не указан, Pig будет использовать bytearray для обозначения неизвестного типа. Если количество полей неизвестно, Pig определит неизвестную схему.

/* The field data types are not specified ... */
a = load '1.txt' as (a0, b0);
a: {a0: bytearray,b0: bytearray}

/* The number of fields is not known ... */
a = load '1.txt';
a: Schema for a unknown

Как Pig обрабатывает схему

Как показано выше, с некоторыми исключениями Pig может вывести схему отношения заранее. Вы можете проверить схему конкретного отношения, используя DESCRIBE. Pig обеспечивает соответствие этой вычисленной схеме во время фактического выполнения, приводя входные данные к ожидаемому типу данных. Если процесс завершается успешно, результаты возвращаются пользователю; в противном случае для каждой записи, которая не смогла преобразовать, генерируется предупреждение. Обратите внимание, что Pig не знает фактические типы полей в входных данных до начала выполнения; вместо этого Pig определяет типы данных и выполняет необходимые преобразования на лету.

Определённая схема — очень мощный инструмент, но иногда это может сказаться на производительности. Рассмотрите следующий пример:

A = load 'input' as (x, y, z);
B = foreach A generate x+y;

Если вы выполните DESCRIBE для B, вы увидите единственный столбец типа double. Это связано с тем, что Pig выбирает самый безопасный вариант и использует самый большой числовой тип, когда схема неизвестна. На практике входные данные могут содержать целочисленные значения; однако Pig приведёт данные к типу double и убедится, что будет возвращено значение double.

Если схема отношения не может быть определена, Pig просто использует данные во время выполнения и распространяет их через конвейер.

Схемы с операторами LOAD и STREAM

С операторами LOAD и STREAM схема, следующая за ключевым словом AS, должна быть заключена в скобки.

В этом примере оператор LOAD содержит определение схемы для простых типов данных.

A = LOAD 'data' AS (f1:int, f2:int);

Схемы с оператором FOREACH

С операторами FOREACH схема, следующая за ключевым словом AS, должна быть заключена в скобки, когда используется оператор FLATTEN. В противном случае схема не должна быть заключена в скобки.

В этом примере оператор FOREACH включает FLATTEN и схему для простых типов данных.

X = FOREACH C GENERATE FLATTEN(B) AS (f1:int, f2:int, f3:int), group;

В этом примере оператор FOREACH включает схему для простого выражения.

X = FOREACH A GENERATE f1+f2 AS x1:int;

В этом примере оператор FOREACH включает схемы для нескольких полей.

X = FOREACH A GENERATE f1 as user, f2 as age, f3 as gpa;

Схемы для простых типов данных

Простые типы данных включают int, long, float, double, chararray, bytearray, boolean, datetime, biginteger и bigdecimal.

Синтаксис

(alias[:type]) [, (alias[:type]) …] )

Термины

alias

Назначаемое имя поля.

type

(Необязательно) Назначаемый простой тип данных поля.

Имя поля и тип отделены двоеточием ( : ).

Если тип опущен, поле по умолчанию имеет тип bytearray.

( , )

Несколько полей заключаются в скобки и разделяются запятыми.

Примеры

В этом примере схема определяет несколько типов.

cat student;
John	18	4.0
Mary	19   	3.8
Bill	20   	3.9
Joe	18   	3.8

A = LOAD 'student' AS (name:chararray, age:int, gpa:float);

DESCRIBE A;
A: {name: chararray,age: int,gpa: float}

DUMP A;
(John,18,4.0F)
(Mary,19,3.8F)
(Bill,20,3.9F)
(Joe,18,3.8F)

В этом примере поле «gpa» по умолчанию будет иметь тип bytearray, потому что тип не объявлен.

cat student;
John	18	4.0
Mary	19	3.8
Bill	20	3.9
Joe	18	3.8

A = LOAD 'data' AS (name:chararray, age:int, gpa);

DESCRIBE A;
A: {name: chararray,age: int,gpa: bytearray}

DUMP A;
(John,18,4.0)
(Mary,19,3.8)
(Bill,20,3.9)
(Joe,18,3.8)

Схемы для сложных типов данных

Сложные типы данных включают кортежи, множества и карты.

Схемы кортежей

Кортеж — это упорядоченный набор полей.

Синтаксис

alias[:tuple] (alias[:type]) [, (alias[:type]) …] )

Термины

alias

Назначаемое имя кортежу.

:tuple

(Необязательно) Тип данных, кортеж (регистр не учитывается).

( )

Обозначение кортежа, круглые скобки.

alias[:type]

Составные части кортежа, где правила определения схемы соответствующего типа применяются к составным частям кортежа:

  • alias — назначаемое имя поля

  • type (необязательно) — простой или сложный тип данных, назначаемый полю

Примеры

В этом примере схема определяет одну кортеж. Операторы загрузки эквивалентны.

cat data;
(3,8,9)
(1,4,7)
(2,5,8)

A = LOAD 'data' AS (T: tuple (f1:int, f2:int, f3:int));
A = LOAD 'data' AS (T: (f1:int, f2:int, f3:int));

DESCRIBE A;
A: {T: (f1: int,f2: int,f3: int)}

DUMP A;
((3,8,9))
((1,4,7))
((2,5,8))

В этом примере схема определяет две кортежи.

cat data;
(3,8,9) (mary,19)
(1,4,7) (john,18)
(2,5,8) (joe,18)

A = LOAD data AS (F:tuple(f1:int,f2:int,f3:int),T:tuple(t1:chararray,t2:int));

DESCRIBE A;
A: {F: (f1: int,f2: int,f3: int),T: (t1: chararray,t2: int)}

DUMP A;
((3,8,9),(mary,19))
((1,4,7),(john,18))
((2,5,8),(joe,18))

Схемы набора

Набор — это коллекция кортежей.

Синтаксис

псевдоним[:набор] {кортеж}

Термины

псевдоним

Имя, присвоенное набору.

:набор

(Необязательно) Тип данных, набор (регистр не учитывается).

{ }

Обозначение для набора, набор фигурных скобок.

кортеж

Кортеж (см. Схему кортежа).

Примеры

В этом примере схема определяет набор. Два оператора загрузки эквивалентны.

cat data;
{(3,8,9)}
{(1,4,7)}
{(2,5,8)}

A = LOAD 'data' AS (B: bag {T: tuple(t1:int, t2:int, t3:int)});
A = LOAD 'data' AS (B: {T: (t1:int, t2:int, t3:int)});

DESCRIBE A:
A: {B: {T: (t1: int,t2: int,t3: int)}}

DUMP A;
({(3,8,9)})
({(1,4,7)})
({(2,5,8)})

Схемы отображения

Отображение — это набор пар ключ-значение.

Синтаксис (<> обозначает необязательность)

псевдоним<:отображение> [ <тип> ]

Термины

псевдоним

Имя, присвоенное отображению.

:отображение

(Необязательно) Тип данных, отображение (регистр не учитывается).

[ ]

Обозначение отображения, набор квадратных скобок.

тип

(Необязательно) Тип данных (все разрешённые типы, по умолчанию — bytearray).

Тип относится только к значению отображения; ключ отображения всегда имеет тип chararray (см. Отображение).

Если тип объявлен, все значения в отображении должны быть этого типа.

Примеры

В этом примере схема определяет неопределённое отображение (значения отображения по умолчанию — bytearray). Операторы загрузки эквивалентны.

cat data;
[open#apache]
[apache#hadoop]

A = LOAD 'data' AS (M:map []);
A = LOAD 'data' AS (M:[]);

DESCRIBE A;
a: {M: map[ ]}

DUMP A;
([open#apache])
([apache#hadoop])

Этот пример демонстрирует использование типизированных отображений.

/* Map types are declared*/
a = load '1.txt' as(map[int]); --Map value is int
b = foreach a generate (map[(i:int)])a0; -- Map value is tuple
b = stream a through `cat` as (m:map[{(i:int,j:chararray)}]); -- Map value is bag

/* The MapLookup of a typed map will result in a datatype of the map value */
a = load '1.txt' as(map[int]);
b = foreach a generate $0#'key';

/* Schema for b */
b: {int}

Схемы для нескольких типов

Вы можете определить схемы для данных, включающих несколько типов.

Пример

В этом примере схема определяет кортеж, набор и отображение.

A = LOAD 'mydata' AS (T1:tuple(f1:int, f2:int), B:bag{T2:tuple(t1:float,t2:float)}, M:map[] );

A = LOAD 'mydata' AS (T1:(f1:int, f2:int), B:{T2:(t1:float,t2:float)}, M:[] );
Сокращение предыдущего отношения

Существует сокращённая форма для ссылки на отношение на предыдущей строке сценария Pig или сессии Grunt:

a = load 'thing' as (x:int);
b = foreach @ generate x;
c = foreach @ generate x;
d = foreach @ generate x;

Арифметические операторы и многое другое

Арифметические операторы

Описание

Оператор

Символ

Примечания

сложение

+

вычитание

-

умножение

*

деление

/

остаток от деления

%

Возвращает остаток от деления a на b (a%b).

Работает с целыми числами (int, long).

условное выражение

? :

(условие ? значение_если_истина : значение_если_ложь)

Условное выражение должно быть заключено в скобки.

Схемы для двух условных результатов условного выражения должны совпадать.

Используйте только выражения (реляционные операторы запрещены).

случай

CASE WHEN THEN ELSE END

CASE выражение [ WHEN значение THEN значение ]+ [ ELSE значение ]? END

CASE [ WHEN условие THEN значение ]+ [ ELSE значение ]? END

Оператор CASE эквивалентен вложенным операторам условных выражений.

Схемы для всех результатов ветвей when/else должны совпадать.

Используйте только выражения (реляционные операторы запрещены).

Примеры

Предположим, у нас есть отношение A.

A = LOAD 'data' AS (f1:int, f2:int, B:bag{T:tuple(t1:int,t2:int)});

DUMP A;
(10,1,{(2,3),(4,6)})
(10,3,{(2,3),(4,6)})
(10,6,{(2,3),(4,6),(5,7)})

В этом примере используется оператор остатка от деления с полями f1 и f2.

X = FOREACH A GENERATE f1, f2, f1%f2;

DUMP X;
(10,1,0)
(10,3,1)
(10,6,4)

В этом примере используется оператор условного выражения с полями f2 и B. Условие: «f2 равно 1»; если условие истинно, возвращается 1; если условие ложно, возвращается количество кортежей в B.

X = FOREACH A GENERATE f2, (f2==1?1:COUNT(B));

DUMP X;
(1,1L)
(3,2L)
(6,3L)

В этом примере используется оператор case с полем f2. Выражение: «f2 % 2»; если выражение равно 0, возвращается 'even'; если выражение равно 1, возвращается 'odd'.

X = FOREACH A GENERATE f2, (
  CASE f2 % 2
    WHEN 0 THEN 'even'
    WHEN 1 THEN 'odd'
  END
);
DUMP X;
(1,odd)
(3,odd)
(6,even)

Это также можно записать следующим образом:

X = FOREACH A GENERATE f2, (
  CASE
    WHEN f2 % 2 == 0 THEN 'even'
    WHEN f2 % 2 == 1 THEN 'odd'
  END
);
DUMP X;
(1,odd)
(3,odd)
(6,even)
Таблица типов: операторы сложения (+) и вычитания (-)

* bytearray преобразуется к этому типу данных

набор

кортеж

отображение

int

long

float

double

chararray

bytearray

набор

ошибка

ошибка

ошибка

ошибка

ошибка

ошибка

ошибка

ошибка

ошибка

кортеж

еще нет

ошибка

ошибка

ошибка

ошибка

ошибка

ошибка

ошибка

отображение

ошибка

ошибка

ошибка

ошибка

ошибка

ошибка

ошибка

int

int

long

float

double

ошибка

преобразование к int

long

long

float

double

ошибка

преобразование к long

float

float

double

ошибка

преобразование к float

double

double

ошибка

преобразование к double

chararray

ошибка

ошибка

bytearray

преобразование к double

Таблица типов: операторы умножения (*) и деления (/)

* bytearray преобразуется к этому типу данных

мешок

кортеж

карта

целое

длинное

вещественное

двойное

символьный массив

байтовый массив

мешок

ошибка

ошибка

ошибка

ещё нет

ещё нет

ещё нет

ещё нет

ошибка

ошибка

кортеж

ошибка

ошибка

ещё нет

ещё нет

ещё нет

ещё нет

ошибка

ошибка

карта

ошибка

ошибка

ошибка

ошибка

ошибка

ошибка

ошибка

целое

целое

длинное

вещественное

двойное

ошибка

преобразование к целому

длинное

длинное

вещественное

двойное

ошибка

преобразование к длинному

вещественное

вещественное

двойное

ошибка

преобразование к вещественному

двойное

двойное

ошибка

преобразование к двойному

символьный массив

ошибка

ошибка

байтовый массив

преобразование к двойному

Таблица типов: оператор modulo (%)

целое

длинное

байтовый массив

целое

целое

длинное

преобразование к целому

длинное

длинное

преобразование к длинному

байтовый массив

ошибка

Булевы операторы

Описание

Оператор

Символ

Примечания

И

и

ИЛИ

или

В

в

Оператор В эквивалентен вложенным операторам ИЛИ.

НЕ

не

Результат булевого выражения (выражения, которое включает булевы и сравнительные операторы) всегда имеет тип boolean (истина или ложь).

Пример
X = FILTER A BY (f1==8) OR (NOT (f2+f3 > f1)) OR (f1 IN (9, 10, 11));

Операторы преобразования типов

Описание

Pig Latin поддерживает преобразования типов, как показано в этой таблице.

от / до

мешок

кортеж

карта

целое

длинное целое

вещественное

двойное вещественное

символьный массив

байтовый массив

логическое

мешок

ошибка

ошибка

ошибка

ошибка

ошибка

ошибка

ошибка

ошибка

ошибка

кортеж

ошибка

ошибка

ошибка

ошибка

ошибка

ошибка

ошибка

ошибка

ошибка

карта

ошибка

ошибка

ошибка

ошибка

ошибка

ошибка

ошибка

ошибка

ошибка

целое

ошибка

ошибка

ошибка

да

да

да

да

ошибка

ошибка

длинное целое

ошибка

ошибка

ошибка

да

да

да

да

ошибка

ошибка

вещественное

ошибка

ошибка

ошибка

да

да

да

да

ошибка

ошибка

двойное вещественное

ошибка

ошибка

ошибка

да

да

да

да

ошибка

ошибка

символьный массив

ошибка

ошибка

ошибка

да

да

да

да

ошибка

да

байтовый массив

да

да

да

да

да

да

да

да

да

логическое

ошибка

ошибка

ошибка

ошибка

ошибка

ошибка

ошибка

да

ошибка

Синтаксис

{(тип_данных) | (кортеж(тип_данных)) | (мешок{кортеж(тип_данных)}) | (карта[]) } поле

Термины

(тип_данных)

Тип данных, к которому вы хотите привести, заключённый в скобки. Можно привести к любому типу, кроме bytearray (см. таблицу выше).

поле

Поле, тип которого вы хотите изменить.

Поле может быть представлено позиционным обозначением или по имени (псевдониму). Например, если f1 - первое поле и тип int, можно привести к типу long, используя (long)$0 или (long)f1.

Использование

Операторы приведения позволяют приводить или преобразовывать данные из одного типа в другой, если преобразование поддерживается (см. таблицу выше). Например, предположим, у вас есть поле целого типа, myint, которое вы хотите преобразовать в строку. Вы можете привести это поле из int в chararray, используя (chararray)myint.

Обратите внимание на следующее:

  • Поле можно явно привести к другому типу. После приведения поле сохраняет новый тип (оно не автоматически возвращается к исходному типу). В этом примере $0 явно приводится к типу int.

    B = FOREACH A GENERATE (int)$0 + 1;
    
  • По возможности, Pig выполняет неявные приведения. В этом примере $0 приводится к типу int (независимо от базовых данных), а $1 - к типу double.

    B = FOREACH A GENERATE $0 + 1, $1 + 1.0
    
  • Когда два байтовых массива используются в арифметических выражениях или выражение байтового массива используется с встроенными агрегатными функциями (такими как SUM), они неявно приводятся к типу double. Если базовые данные действительно int или long, вы получите лучшую производительность, объявив тип или явно приведя данные.

  • Приведение к меньшему типу может привести к потере данных. Например, приведение от long к int может привести к потере битов.

Примеры

В этом примере целое число приводится к типу chararray (см. отношение X).

A = LOAD 'data' AS (f1:int,f2:int,f3:int);

DUMP A;
(1,2,3)
(4,2,1)
(8,3,4)
(4,3,3)
(7,2,5)
(8,4,3)

B = GROUP A BY f1;

DUMP B;
(1,{(1,2,3)})
(4,{(4,2,1),(4,3,3)})
(7,{(7,2,5)})
(8,{(8,3,4),(8,4,3)})

DESCRIBE B;
B: {group: int,A: {f1: int,f2: int,f3: int}}

X = FOREACH B GENERATE group, (chararray)COUNT(A) AS total;
(1,1)
(4,2)
(7,1)
(8,2)

DESCRIBE X;
X: {group: int,total: chararray}

В этом примере байтовый массив (fld в отношении A) приводится к типу кортеж.

cat data;
(1,2,3)
(4,2,1)
(8,3,4)

A = LOAD 'data' AS fld:bytearray;

DESCRIBE A;
a: {fld: bytearray}

DUMP A;
((1,2,3))
((4,2,1))
((8,3,4))

B = FOREACH A GENERATE (tuple(int,int,float))fld;

DESCRIBE B;
b: {(int,int,float)}

DUMP B;
((1,2,3))
((4,2,1))
((8,3,4))

В этом примере байтовый массив (fld в отношении A) приводится к типу мешок.

cat data;
{(4829090493980522200L)}
{(4893298569862837493L)}
{(1297789302897398783L)}

A = LOAD 'data' AS fld:bytearray;

DESCRIBE A;
A: {fld: bytearray}

DUMP A;
({(4829090493980522200L)})
({(4893298569862837493L)})
({(1297789302897398783L)})

B = FOREACH A GENERATE (bag{tuple(long)})fld; 

DESCRIBE B;
B: {{(long)}}

DUMP B;
({(4829090493980522200L)})
({(4893298569862837493L)})
({(1297789302897398783L)})

В этом примере байтовый массив (fld в отношении A) приводится к типу карта.

cat data;
[open#apache]
[apache#hadoop]
[hadoop#pig]
[pig#grunt]

A = LOAD 'data' AS fld:bytearray;

DESCRIBE A;
A: {fld: bytearray}

DUMP A;
([open#apache])
([apache#hadoop])
([hadoop#pig])
([pig#grunt])

B = FOREACH A GENERATE ((map[])fld;

DESCRIBE B;
B: {map[ ]}

DUMP B;
([open#apache])
([apache#hadoop])
([hadoop#pig])
([pig#grunt])

Преобразование отношений в скаляры

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

Преобразованное отношение может быть использовано в любом месте, где выражение данного типа имеет смысл, включая FOREACH, FILTER и SPLIT. Обратите внимание, что если явное преобразование не используется, Pig вставит неявное преобразование в соответствии с правилами Pig. Также, когда схема не может быть определена, используется bytearray.

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

В этом примере вычисляется процент кликов, принадлежащих конкретному пользователю. Для оператора FOREACH используется явное преобразование. Если SUM не присвоено имя, можно использовать позицию (userid, clicks/(double)C.$0).

A = load 'mydata' as (userid, clicks); 
B = group A all; 
C = foreach B genertate SUM(A.clicks) as total; 
D = foreach A generate userid, clicks/(double)C.total; 
dump D;

В этом примере используется многопольный кортеж. Для оператора FILTER Pig выполняет неявное преобразование. Для оператора FOREACH используется явное преобразование.

A = load 'mydata' as (userid, clicks); 
B = group A all; 
C = foreach B genertate SUM(A.clicks) as total, COUNT(A) as cnt; 
D = FILTER A by clicks > C.total/3 
E = foreach D generate userid, clicks/(double)C.total, cnt; 
dump E; 

Операторы сравнения

Описание

Оператор

Символ

Примечания

равно

==

не равно

!=

меньше чем

<

больше чем

>

меньше или равно

<=

больше или равно

>=

сопоставление с шаблоном

matches

Принимает выражение слева и строковую константу справа.

выражение matches строковая-константа

Используйте формат Java формат для регулярных выражений.

Используйте операторы сравнения с числовыми и строковыми данными.

Примеры

Числовой пример

X = FILTER A BY (f1 == 8);

Строковый пример

X = FILTER A BY (f2 == 'apache');

Пример сопоставления

X = FILTER A BY (f1 matches '.*apache.*');

Таблица типов: оператор равно (==)

bag

tuple

map

int

long

float

double

chararray

bytearray

boolean

datetime

biginteger

bigdecimal

bag

error

error

error

error

error

error

error

error

error

error

error

error

error

tuple

boolean

(see Note 1)

error

error

error

error

error

error

error

error

error

error

error

map

boolean

(see Note 2)

error

error

error

error

error

error

error

error

error

error

int

boolean

boolean

boolean

boolean

error

cast as boolean

error

error

error

error

long

boolean

boolean

boolean

error

cast as boolean

error

error

error

error

float

boolean

boolean

error

cast as boolean

error

error

error

error

double

boolean

error

cast as boolean

error

error

error

error

chararray

boolean

cast as boolean

error

error

error

error

bytearray

boolean

error

error

error

error

boolean

boolean

error

error

error

datetime

boolean

error

error

biginteger

boolean

error

bigdecimal

boolean

Примечание 1: boolean (Кортеж A равен кортежу B, если они имеют один и тот же размер s, и для всех 0 <= i < s A[i] == B[i])

Примечание 2: boolean (Карта A равна карте B, если A и B имеют одинаковое количество записей, и для каждого ключа k1 в A со значением v1 существует ключ k2 в B со значением v2, такой что k1 == k2 и v1 == v2)

Таблица типов: оператор неравенства (!=)

мешок

кортеж

карта

int

long

float

double

chararray

bytearray

boolean

datetime

biginteger

bigdecimal

мешок

ошибка

ошибка

ошибка

ошибка

ошибка

ошибка

ошибка

ошибка

ошибка

ошибка

ошибка

ошибка

ошибка

кортеж

ошибка

ошибка

ошибка

ошибка

ошибка

ошибка

ошибка

ошибка

ошибка

ошибка

ошибка

ошибка

карта

ошибка

ошибка

ошибка

ошибка

ошибка

ошибка

ошибка

ошибка

ошибка

ошибка

ошибка

int

boolean

boolean

boolean

boolean

ошибка

boolean (bytearray cast as int)

ошибка

ошибка

ошибка

ошибка

long

boolean

boolean

boolean

ошибка

boolean (bytearray cast as long)

ошибка

ошибка

ошибка

ошибка

float

boolean

boolean

ошибка

boolean (bytearray cast as float)

ошибка

ошибка

ошибка

ошибка

double

boolean

ошибка

boolean (bytearray cast as double)

ошибка

ошибка

ошибка

ошибка

chararray

boolean

boolean (bytearray cast as chararray)

ошибка

ошибка

ошибка

ошибка

bytearray

boolean

ошибка

ошибка

ошибка

ошибка

boolean

boolean

ошибка

ошибка

ошибка

datetime

boolean

ошибка

ошибка

biginteger

boolean

ошибка

bigdecimal

boolean

Таблица типов: оператор matches

*Преобразование в chararray (второй аргумент должен быть chararray)

chararray

bytearray*

chararray

boolean

boolean

bytearray

boolean

boolean

Операторы построения типов

Описание

Оператор

Символ

Примечания

Конструктор кортежа

( )

Используется для построения кортежа из указанных элементов. Эквивалентно TOTUPLE.

Конструктор мешка

{ }

Используется для построения мешка из указанных элементов. Эквивалентно TOBAG.

Конструктор карты

[ ]

Используется для построения карты из указанных элементов. Эквивалентно TOMAP.

Обратите внимание на следующее:

  • Эти операторы могут использоваться везде, где допустимо выражение соответствующего типа, включая FOREACH GENERATE, FILTER и т.д.
  • Один элемент, заключенный в скобки ( ), например (5), не считается кортежем, а скорее арифметическим оператором.
  • Для мешков каждый элемент помещается в мешок; если элемент не является кортежем, Pig создаст для него кортеж:
    • При этом {$1, $2} Pig создает это {($1), ($2)} мешок с двумя кортежами

      ... ни $1, ни $2 не являются кортежами, поэтому Pig создает кортеж вокруг каждого элемента

    • При этом {($1), $2} Pig создает это {($1), ($2)} мешок с двумя кортежами

      ... поскольку ($1) обрабатывается как $1 (нельзя создать кортеж с одним элементом, используя этот синтаксис), {($1), $2} становится {$1, $2}, и Pig создает кортеж вокруг каждого элемента

    • При этом {($1, $2)} Pig создает это {($1, $2)} мешок с одним кортежем

      ... Pig создает кортеж ($1, $2), а затем помещает этот кортеж в мешок

Примеры

Построение кортежа

A = load 'students' as (name:chararray, age:int, gpa:float);
B = foreach A generate (name, age);
store B into 'results';

Input (students):
joe smith  20  3.5
amy chen   22  3.2
leo allen  18  2.1

Output (results):
(joe smith,20)
(amy chen,22)
(leo allen,18)

Построение мешка

A = load 'students' as (name:chararray, age:int, gpa:float);
B = foreach A generate {(name, age)}, {name, age};
store B into 'results';

Input (students):
joe smith  20  3.5
amy chen   22  3.2
leo allen  18  2.1

Output (results):
{(joe smith,20)}   {(joe smith),(20)}
{(amy chen,22)}    {(amy chen),(22)}
{(leo allen,18)}   {(leo allen),(18)}

Построение карты

A = load 'students' as (name:chararray, age:int, gpa:float);
B = foreach A generate [name, gpa];
store B into 'results';

Input (students):
joe smith  20  3.5
amy chen   22  3.2
leo allen  18  2.1

Output (results):
[joe smith#3.5]
[amy chen#3.2]
[leo allen#2.1]

Операторы косвенной ссылки

Описание

Оператор

Символ

Замечания

Распаковка кортежа

tuple.id или tuple.(id,…)

Распаковка кортежа может выполняться по имени (tuple.field_name) или по позиции (mytuple.$0). Если разыменовывается набор полей (tuple.(name1, name2) или tuple.($0, $1)), выражение представляет кортеж, составленный из указанных полей. Обратите внимание, что если оператор точки применяется к bytearray, bytearray будет считаться кортежем.

Распаковка мешка

bag.id или bag.(id,…)

Распаковка мешка может выполняться по имени (bag.field_name) или по позиции (bag.$0). Если разыменовывается набор полей (bag.(name1, name2) или bag.($0, $1)), выражение представляет мешок, составленный из указанных полей.

Распаковка отображения

map#'key'

Распаковка отображения должна выполняться по ключу (field_name#key или $0#key). Если оператор фунта применяется к bytearray, bytearray считается отображением. Если ключ не существует, возвращается пустая строка.

Примеры

Пример с кортежем

Предположим, у нас есть отношение A.

A = LOAD 'data' as (f1:int, f2:tuple(t1:int,t2:int,t3:int));

DUMP A;
(1,(1,2,3))
(2,(4,5,6))
(3,(7,8,9))
(4,(1,4,7))
(5,(2,5,8))

В этом примере используется разыменование для извлечения двух полей из кортежа f2.

X = FOREACH A GENERATE f2.t1,f2.t3;

DUMP X;
(1,3)
(4,6)
(7,9)
(1,7)
(2,8)

Пример с мешком

Предположим, у нас есть отношение B, сформированное путём группировки отношения A (см. оператор GROUP для получения информации о именах полей в отношении B).

A = LOAD 'data' AS (f1:int, f2:int,f3:int);

DUMP A;
(1,2,3)
(4,2,1)
(8,3,4)
(4,3,3)
(7,2,5)
(8,4,3)

B = GROUP A BY f1;

DUMP B;
(1,{(1,2,3)})
(4,{(4,2,1),(4,3,3)})
(7,{(7,2,5)})
(8,{(8,3,4),(8,4,3)})

ILLUSTRATE B;
etc …
----------------------------------------------------------
| b   | group: int | a: bag({f1: int,f2: int,f3: int}) |
----------------------------------------------------------

В этом примере используется разыменование с отношением X для проекции первого поля (f1) каждого кортежа в мешке (a).

X = FOREACH B GENERATE a.f1;

DUMP X;
({(1)})
({(4),(4)})
({(7)})
({(8),(8)})

Пример кортеж/мешок

Предположим, у нас есть отношение B, сформированное путём группировки отношения A (см. оператор GROUP для получения информации о именах полей в отношении B).

A = LOAD 'data' AS (f1:int, f2:int, f3:int);

DUMP A;
(1,2,3)
(4,2,1)
(8,3,4)
(4,3,3)
(7,2,5)
(8,4,3)

B = GROUP A BY (f1,f2);

DUMP B;
((1,2),{(1,2,3)})
((4,2),{(4,2,1)})
((4,3),{(4,3,3)})
((7,2),{(7,2,5)})
((8,3),{(8,3,4)})
((8,4),{(8,4,3)})

ILLUSTRATE B;
etc …
-------------------------------------------------------------------------------
| b     | group: tuple({f1: int,f2: int}) | a: bag({f1: int,f2: int,f3: int}) |
-------------------------------------------------------------------------------
|       | (8, 3)                                | {(8, 3, 4), (8, 3, 4)} |
-------------------------------------------------------------------------------

В этом примере используется разыменование для проекции поля (f1) из кортежа (группа) и поля (f1) из мешка (a).

X = FOREACH B GENERATE group.f1, a.f1;

DUMP X;
(1,{(1)})
(4,{(4)})
(4,{(4)})
(7,{(7)})
(8,{(8)})
(8,{(8)})

Пример с отображением

Предположим, у нас есть отношение A.

A = LOAD 'data' AS (f1:int, f2:map[]);

DUMP A;
(1,[open#apache])
(2,[apache#hadoop])
(3,[hadoop#pig])
(4,[pig#grunt])

В этом примере разыменование используется для поиска значения ключа 'open'.

X = FOREACH A GENERATE f2#'open';

DUMP X;
(apache)
()
()
()

Оператор развязки

Используйте оператор развязки ( :: ) для идентификации имён полей после операторов JOIN, COGROUP, CROSS или FLATTEN.

В этом примере, чтобы развязать y, используйте A::y или B::y. В случаях, когда нет неоднозначности, например, z, оператор :: не нужен, но всё же поддерживается.

A = load 'data1' as (x, y);
B = load 'data2' as (x, y, z);
C = join A by x, B by x;
D = foreach C generate y; -- which y?

Оператор сглаживания

Оператор FLATTEN синтаксически похож на UDF, но на самом деле это оператор, изменяющий структуру кортежей и мешков таким образом, как не может сделать UDF. Flatten распаковывает вложенные кортежи и мешки. Идея та же, но операция и результат отличаются для каждого типа структуры.

Для кортежей flatten заменяет поля кортежа вместо самого кортежа. Например, рассмотрим отношение, имеющее кортеж вида (a, (b, c)). Выражение GENERATE $0, flatten($1) заставит этот кортеж стать (a, b, c).

Для мешков ситуация становится сложнее. Когда мы распаковываем мешок, мы создаём новые кортежи. Если у нас есть отношение, состоящее из кортежей вида ({(b,c),(d,e)}) и мы применяем GENERATE flatten($0), мы получим два кортежа (b,c) и (d,e). Когда мы удаляем уровень вложенности в мешке, иногда мы вызываем кросс-продукт. Например, рассмотрим отношение, имеющее кортеж вида (a, {(b,c), (d,e)}), часто генерируемое оператором GROUP. Если мы применим выражение GENERATE $0, flatten($1) к этому кортежу, мы создадим новые кортежи: (a, b, c) и (a, d, e).

Также обратите внимание, что flatten пустого мешка приведёт к тому, что эта строка будет отброшена; вывод не будет сгенерирован. (См. также Удаление пустых значений перед соединением.)

grunt> cat empty.bag
{}      1
grunt> A = LOAD 'empty.bag' AS (b : bag{}, i : int);
grunt> B = FOREACH A GENERATE flatten(b), i;
grunt> DUMP B;
grunt>

Примеры использования оператора FLATTEN см. в FOREACH.

Операторы обработки NULL

Описание

Оператор

Символ

Замечания

равен null

is null

не равен null

is not null

Подробное обсуждение NULL см. в NULL и Pig Latin.

Примеры

В этом примере получены значения, не являющиеся NULL.

X = FILTER A BY f1 is not null;

Таблица типов

Операторы NULL могут применяться ко всем типам данных (см. NULL и Pig Latin).

Операторы знаков

Описание

Оператор

Символ

Замечания

положительный

+

Не оказывает влияния.

отрицательный (отрицание)

-

Изменяет знак положительного или отрицательного числа.

Примеры

В этом примере оператор отрицания применяется к значениям "x".

A = LOAD 'data' as (x, y, z);

B = FOREACH A GENERATE -x, y;

Таблица типов: оператор отрицания ( -)

мешок

ошибка

кортеж

ошибка

отображение

ошибка

int

int

long

long

float

float

double

double

chararray

ошибка

bytearray

double (как double)

datetime

ошибка

biginteger

biginteger

bigdecimal

bigdecimal

Операторы соотношений

ASSERT

Утверждение условия на данных.

Синтаксис

ASSERT alias BY выражение [, сообщение];

Термины

alias

Имя отношения.

BY

Обязательное ключевое слово.

выражение

Булево выражение.

сообщение

Сообщение об ошибке при провале утверждения.

Использование

Используйте assert для проверки истинности условия на данных. Обработка завершается ошибкой, если какое-либо из записей нарушает условие.

Примеры

Предположим, у нас есть отношение A.

A = LOAD 'data' AS (a0:int,a1:int,a2:int);

DUMP A;
(1,2,3)
(4,2,1)
(8,3,4)
(4,3,3)
(7,2,5)
(8,4,3)

Теперь вы можете утверждать, что столбец a0 в ваших данных больше 0, и возвращать ошибку в противном случае

ASSERT A by a0 > 0, 'a0 should be greater than 0';

COGROUP

См. оператор GROUP.

CROSS

Вычисляет декартово произведение двух или более отношений.

Синтаксис

alias = CROSS alias, alias [, alias …] [PARTITION BY partitioner] [PARALLEL n];

Термины

alias

Имя отношения.

PARTITION BY partitioner

Используйте эту опцию для указания Hadoop Partitioner. Partitioner управляет разделением ключей промежуточных результатов map-фазы.

  • Дополнительную информацию смотрите на http://hadoop.apache.org/docs/current/api/org/apache/hadoop/mapred/Partitioner.html

  • Пример использования смотрите в Пример: PARTITION BY

PARALLEL n

Увеличить параллелизм задания, указав количество задач reduce, n.

Дополнительную информацию смотрите в Использование Параллельных Функций.

Использование

Используйте оператор CROSS для вычисления декартова произведения двух или более отношений.

CROSS — это дорогостоящая операция и следует использовать её экономно.

Пример

Предположим, у нас есть отношения A и B.

A = LOAD 'data1' AS (a1:int,a2:int,a3:int);

DUMP A;
(1,2,3)
(4,2,1)

B = LOAD 'data2' AS (b1:int,b2:int);

DUMP B;
(2,4)
(8,9)
(1,3)

В этом примере вычисляется декартово произведение отношения A и B.

X = CROSS A, B;

DUMP X;
(1,2,3,2,4)
(1,2,3,8,9)
(1,2,3,1,3)
(4,2,1,2,4)
(4,2,1,8,9)
(4,2,1,1,3)

CUBE

Выполняет операции куба/rollup.

Операция куба

Операция куба вычисляет агрегаты для всех возможных комбинаций указанных измерений группировки. Количество комбинаций группировки, генерируемых операцией куба для n измерений, будет равно 2^n.

Операция rollup

Операция rollup вычисляет несколько уровней агрегатов, основанных на иерархическом порядке указанных измерений группировки. Rollup полезен, когда измерения упорядочены иерархически. Количество комбинаций группировки, генерируемых операцией rollup для n измерений, будет равно n+1.

Синтаксис

alias = CUBE alias BY { CUBE выражение | ROLLUP выражение }, [ CUBE выражение | ROLLUP выражение ] [PARALLEL n];

Термины

alias

Имя отношения.

CUBE

Ключевое слово

BY

Ключевое слово

выражение

Проекции (измерения) отношения. Поддерживаются выражения для полей, звёзд и диапазонов проекций.

ROLLUP

Ключевое слово

PARALLEL n

Увеличить параллелизм задания, указав количество задач reduce, n.

Дополнительную информацию смотрите в Использование Параллельных Функций.

Пример

Основное использование операции CUBE

salesinp = LOAD '/pig/data/salesdata' USING PigStorage(',') AS
    (product:chararray, year:int, region:chararray, state:chararray, city:chararray, sales:long);
cubedinp = CUBE salesinp BY CUBE(product,year);
result = FOREACH cubedinp GENERATE FLATTEN(group), SUM(cube.sales) AS totalsales;

Для входной кортежи (автомобиль, 2012, средний запад, огайо, колумбус, 4000), запрос с операцией куба вернёт

(car,2012,4000)
(car,,4000)
(,2012,4000)
(,,4000)

Схема вывода

grunt> describe cubedinp;
cubedinp: {group: (product: chararray,year: int),cube: {(product: chararray,year: int,region: chararray,
state: chararray,city: chararray,sales: long)}}

Обратите внимание на второй столбец, поле 'cube', которое представляет собой набор всех кортежей, принадлежащих группе. Также обратите внимание, что атрибут измерения 'sales', наряду с другими неиспользуемыми измерениями в операторе загрузки, продвигается вниз, чтобы его можно было использовать позже при вычислении агрегатов измерения, например, в этом случае SUM(cube.sales).

Основное использование операции ROLLUP

salesinp = LOAD '/pig/data/salesdata' USING PigStorage(',') AS
    (product:chararray, year:int, region:chararray, state:chararray, city:chararray, sales:long);
rolledup = CUBE salesinp BY ROLLUP(region,state,city);
result = FOREACH rolledup GENERATE FLATTEN(group), SUM(cube.sales) AS totalsales;

Для входной кортежи (автомобиль, 2012, средний запад, огайо, колумбус, 4000), запрос с операцией rollup вернёт

(midwest,ohio,columbus,4000)
(midwest,ohio,,4000)
(midwest,,,4000)
(,,,4000)

Схема вывода

grunt> describe rolledup;
rolledup: {group: (region: chararray,state: chararray,city: chararray),cube: {(region: chararray,
state: chararray,city: chararray,product: chararray,year: int,sales: long)}}

Основное использование операций CUBE и ROLLUP совместно

Если операции CUBE и ROLLUP используются вместе, выходные группы будут представлять собой декартово произведение всех групп, сгенерированных операциями куба и rollup. Если в операциях куба m измерений, а в операциях rollup n измерений, то общее количество комбинаций будет (2^m) * (n+1).

salesinp = LOAD '/pig/data/salesdata' USING PigStorage(',') AS
    (product:chararray, year:int, region:chararray, state:chararray, city:chararray, sales:long);
cubed_and_rolled = CUBE salesinp BY CUBE(product,year), ROLLUP(region, state, city);
result = FOREACH cubed_and_rolled GENERATE FLATTEN(group), SUM(cube.sales) AS totalsales;

Для входной кортежи (автомобиль, 2012, средний запад, огайо, колумбус, 4000), запрос с операциями куба и rollup вернёт

(car,2012,midwest,ohio,columbus,4000)
(car,2012,midwest,ohio,,4000)
(car,2012,midwest,,,4000)
(car,2012,,,,4000)
(car,,midwest,ohio,columbus,4000)
(car,,midwest,ohio,,4000)
(car,,midwest,,,4000)
(car,,,,,4000)
(,2012,midwest,ohio,columbus,4000)
(,2012,midwest,ohio,,4000)
(,2012,midwest,,,4000)
(,2012,,,,4000)
(,,midwest,ohio,columbus,4000)
(,,midwest,ohio,,4000)
(,,midwest,,,4000)
(,,,,,4000)

Схема вывода

grunt> describe cubed_and_rolled;
cubed_and_rolled: {group: (product: chararray,year: int,region: chararray,
state: chararray,city: chararray),cube: {(product: chararray,year: int,region: chararray,
state: chararray,city: chararray,sales: long)}}

Обработка нулевых значений в измерениях

Поскольку нулевые значения используются для представления подсчётов в операциях куба и rollup, для различения допустимых нулевых значений, которые уже существуют в качестве значений измерения, оператор CUBE преобразует все нулевые значения в измерения в значение "неизвестно" перед выполнением операции куба или rollup. Например, для CUBE(продукт,местоположение) с входной кортежей (автомобиль,) вывод будет

(car,unknown)
(car,)
(,unknown)
(,)

DEFINE

См.:

  • DEFINE (UDFs, потоковая обработка)
  • DEFINE (макросы)

DISTINCT

Удаляет дублирующиеся кортежи в отношении.

Синтаксис

alias = DISTINCT alias [PARTITION BY partitioner] [PARALLEL n];

Термины

alias

Имя отношения.

PARTITION BY partitioner

Используйте эту опцию для указания Hadoop Partitioner. Partitioner управляет разделением ключей промежуточных результатов map-фазы.

  • Дополнительную информацию смотрите на http://hadoop.apache.org/docs/current/api/org/apache/hadoop/mapred/Partitioner.html

  • Пример использования смотрите в Пример: PARTITION BY.

PARALLEL n

Увеличить параллелизм задания, указав количество задач reduce, n.

Дополнительную информацию смотрите в Использование Параллельных Функций.

Использование

Используйте оператор DISTINCT для удаления дублирующихся кортежей в отношении. DISTINCT не сохраняет исходный порядок содержимого (для удаления дубликатов Pig должен сначала отсортировать данные). Вы не можете использовать DISTINCT для подмножества полей; для этого используйте FOREACH и вложенный блок, чтобы сначала выбрать поля, а затем применить DISTINCT (см. Пример: Вложенный блок).

Пример

Предположим, у нас есть отношение A.

A = LOAD 'data' AS (a1:int,a2:int,a3:int);

DUMP A;
(8,3,4)
(1,2,3)        
(4,3,3)        
(4,3,3)        
(1,2,3) 

В этом примере удаляются все дублирующиеся кортежи.

X = DISTINCT A;

DUMP X;
(1,2,3)
(4,3,3)
(8,3,4)

FILTER

Выбирает кортежи из отношения на основе некоторого условия.

Синтаксис

alias = FILTER alias BY выражение;

Термины

alias

Имя отношения.

BY

Обязательное ключевое слово.

выражение

Булево выражение.

Использование

Используйте оператор FILTER для работы с кортежами или строками данных (если вы хотите работать со столбцами данных, используйте операцию FOREACH...GENERATE).

FILTER обычно используется для выбора необходимых данных или, наоборот, для фильтрации (удаления) ненужных данных.

Примеры

Предположим, у нас есть отношение A.

A = LOAD 'data' AS (a1:int,a2:int,a3:int);

DUMP A;
(1,2,3)
(4,2,1)
(8,3,4)
(4,3,3)
(7,2,5)
(8,4,3)

В этом примере условие гласит, что если третье поле равно 3, то кортеж с отношением X включается.

X = FILTER A BY f3 == 3;

DUMP X;
(1,2,3)
(4,3,3)
(8,4,3)

В этом примере условие гласит, что если первое поле равно 8 или если сумма полей f2 и f3 не больше первого поля, то кортеж отношения X включается.

X = FILTER A BY (f1 == 8) OR (NOT (f2+f3 > f1));

DUMP X;
(4,2,1)
(8,3,4)
(7,2,5)
(8,4,3)

FOREACH

Генерирует преобразования данных на основе столбцов данных.

Синтаксис

alias = FOREACH { блок | вложенный_блок };

Термины

alias

Название отношения (внешний пакет).

block

Блок FOREACH…GENERATE, используемый с отношением (внешним пакетом). Используйте такой синтаксис:

alias = FOREACH alias GENERATE expression [AS schema] [expression [AS schema]….];

См. Схемы

nested_block

Вложенный блок FOREACH…GENERATE, используемый с внутренним пакетом. Используйте такой синтаксис:

alias = FOREACH nested_alias {

alias = {nested_op | nested_exp}; [{alias = {nested_op | nested_exp}; …]

GENERATE expression [AS schema] [expression [AS schema]….]

};

Где:

Вложенный блок заключён в открывающие и закрывающие скобки { … }.

Ключевое слово GENERATE должно быть последним оператором вложенного блока.

См. Схемы

Макросы НЕ разрешены внутри вложенного блока.

expression

Выражение.

nested_alias

Название внутреннего пакета.

nested_op

Допустимые операции: CROSS, DISTINCT, FILTER, FOREACH, LIMIT и ORDER BY.

Примечание: Вложенные операторы FOREACH могут быть вложены не более чем на два уровня. Операторы FOREACH, вложенные на три или более уровней, приведут к ошибке синтаксиса.

Вы также можете выполнять проекции внутри вложенного блока.

Примеры см. в Примере: Вложенный блок.

nested_exp

Любое произвольное поддерживаемое выражение.

AS

Ключевое слово

schema

Схема, использующая ключевое слово AS (см. Схемы).

  • Если используется оператор FLATTEN, заключите схему в скобки.

  • Если оператор FLATTEN не используется, не заключайте схему в скобки.

Использование

Используйте операцию FOREACH…GENERATE для работы со столбцами данных (если вы хотите работать с кортежами или строками данных, используйте операцию FILTER).

FOREACH…GENERATE работает как с отношениями (внешними пакетами), так и с внутренними пакетами:

  • Если A — отношение (внешний пакет), оператор FOREACH может выглядеть следующим образом.

    X = FOREACH A GENERATE f1;
    
  • Если A — внутренний пакет, оператор FOREACH может выглядеть следующим образом.

    X = FOREACH B {
            S = FILTER A BY 'xyz';
            GENERATE COUNT (S.$0);
    }
    

Пример: Проекция

В этом примере используется звёздочка (*) для проекции всех полей из отношения A в отношение X. Отношения A и X идентичны.

X = FOREACH A GENERATE *;

DUMP X;
(1,2,3)
(4,2,1)
(8,3,4)
(4,3,3)
(7,2,5)
(8,4,3)

В этом примере два поля из отношения A проектируются для формирования отношения X.

X = FOREACH A GENERATE a1, a2;

DUMP X;
(1,2)
(4,2)
(8,3)
(4,3)
(7,2)
(8,4)

Пример: Вложенная проекция

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

X = FOREACH C GENERATE group, B.b2;

DUMP X;
(1,{(3)})
(4,{(6),(9)})
(8,{(9)})

В этом примере сохраняются несколько вложенных столбцов.

X = FOREACH C GENERATE group, A.(a1, a2);

DUMP X;
(1,{(1,2)})
(4,{(4,2),(4,3)})
(8,{(8,3),(8,4)})

Пример: Схема

В этом примере две поля в отношении A суммируются для формирования отношения X. Для проектируемого поля определена схема.

X = FOREACH A GENERATE a1+a2 AS f1:int;

DESCRIBE X;
x: {f1: int}

DUMP X;
(3)
(6)
(11)
(7)
(9)
(12)

Y = FILTER X BY f1 > 10;

DUMP Y;
(11)
(12)

Пример: Применение функций

В этом примере встроенная функция SUM() используется для суммирования набора чисел в пакете.

X = FOREACH C GENERATE group, SUM (A.a1);

DUMP X;
(1,1)
(4,8)
(8,16)

Пример: Разглаживание

В этом примере используется оператор FLATTEN для устранения вложенности.

X = FOREACH C GENERATE group, FLATTEN(A);

DUMP X;
(1,1,2,3)
(4,4,2,1)
(4,4,3,3)
(8,8,3,4)
(8,8,4,3)

Другой пример FLATTEN.

X = FOREACH C GENERATE GROUP, FLATTEN(A.a3);

DUMP X;
(1,3)
(4,1)
(4,3)
(8,4)
(8,3)

Ещё один пример FLATTEN. Обратите внимание, что для группы '4' в C в каждом пакете есть две кортежи. Таким образом, при разглаживании обоих пакетов возвращается декартово произведение этих кортежей; то есть, кортежи (4, 2, 6), (4, 3, 6), (4, 2, 9) и (4, 3, 9).

X = FOREACH C GENERATE FLATTEN(A.(a1, a2)), FLATTEN(B.$1);

DUMP X;
(1,2,3)
(4,2,6)
(4,2,9)
(4,3,6)
(4,3,9)
(8,3,9)
(8,4,9)

Ещё один пример FLATTEN. Здесь отношения A и B оба имеют столбец x. При формировании отношения E вам нужно использовать оператор :: для идентификации, какой столбец x использовать — столбец x отношения A (A::x) или столбец x отношения B (B::x). В этом примере используется столбец x отношения A (A::x).

A = LOAD 'data' AS (x, y);
B = LOAD 'data' AS (x, z);
C = COGROUP A BY x, B BY x;
D = FOREACH C GENERATE flatten(A), flatten(b);
E = GROUP D BY A::x;
……

Пример: Вложенный блок

В этом примере внутри вложенного блока выполняется CROSS.

user = load 'user' as (uid, age, gender, region);
session = load 'session' as (uid, region);
C = cogroup user by uid, session by uid;
D = foreach C {
    crossed = cross user, session;
    generate crossed;
}
dump D;  

В этом примере оператор FOREACH вложен на второй уровень.

a = load '1.txt' as (a0, a1:chararray, a2:chararray); 
b = group a by a0; 
c = foreach b { 
    c0 = foreach a generate TOMAP(a1,a2); 
    generate c0; 
} 
dump c; 

В этом примере вложены CROSS и FOREACH на второй уровень.

a = load '1.txt' as (a0, a1, a2); 
b = load '2.txt' as (b0, b1); 
c = cogroup a by a0, b by b0; 
d = foreach c { 
    d0 = cross a, b; 
    d1 = foreach d0 generate a1+b1; 
    generate d1; 
} 
dump d;

Предположим, у нас есть отношения A и B. Обратите внимание, что отношение B содержит внутренний пакет.

A = LOAD 'data' AS (url:chararray,outlink:chararray);

DUMP A;
(www.ccc.com,www.hjk.com)
(www.ddd.com,www.xyz.org)
(www.aaa.com,www.cvn.org)
(www.www.com,www.kpt.net)
(www.www.com,www.xyz.org)
(www.ddd.com,www.xyz.org)

B = GROUP A BY url;

DUMP B;
(www.aaa.com,{(www.aaa.com,www.cvn.org)})
(www.ccc.com,{(www.ccc.com,www.hjk.com)})
(www.ddd.com,{(www.ddd.com,www.xyz.org),(www.ddd.com,www.xyz.org)})
(www.www.com,{(www.www.com,www.kpt.net),(www.www.com,www.xyz.org)})

В этом примере мы выполнили две операции, разрешённые в вложенном блоке, FILTER и DISTINCT. Обратите внимание, что последним оператором в вложенном блоке должен быть GENERATE. Также обратите внимание на использование проекции (PA = FA.outlink;) для извлечения поля. DISTINCT может применяться только к подмножеству полей (а не к отношению) внутри вложенного блока.

X = FOREACH B {
        FA= FILTER A BY outlink == 'www.xyz.org';
        PA = FA.outlink;
        DA = DISTINCT PA;
        GENERATE group, COUNT(DA);
}

DUMP X;
(www.aaa.com,0)
(www.ccc.com,0)
(www.ddd.com,1)
(www.www.com,1)

GROUP

Группирует данные в одном или нескольких отношениях.

Примечание: операторы GROUP и COGROUP идентичны. Оба оператора работают с одним или несколькими отношениями. Для лучшей читаемости используется оператор GROUP в утверждениях, относящихся к одному отношению, и оператор COGROUP в утверждениях, относящихся к двум или более отношениям. Одновременно можно COGROUP не более 127 отношений.

Синтаксис

alias = GROUP alias { ALL | BY expression} [, alias ALL | BY expression …] [USING 'collected' | 'merge'] [PARTITION BY partitioner] [PARALLEL n];

Термины

alias

Название отношения.

Одновременно можно COGROUP не более 127 отношений.

ALL

Ключевое слово. Используйте ALL, если вы хотите, чтобы все кортежи попали в одну группу, например, при агрегировании по всему отношению.

B = GROUP A ALL;

BY

Ключевое слово. Используйте эту клаузу для группировки отношения по полю, кортежу или выражению.

B = GROUP A BY f1;

expression

Выражение кортежа. Это ключ или ключевое поле группы. Если результатом выражения кортежа является одно поле, ключом будет значение первого поля, а не кортеж с одним полем. Для группировки по нескольким ключам заключите ключи в скобки:

B = GROUP A BY (key1,key2);

USING

Ключевое слово

'collected'

Используйте клаузу ‘collected’ с операцией GROUP (работает только с одним отношением).

Применяются следующие условия:

  • Загрузчик должен реализовывать интерфейс {CollectableLoader}.

  • Данные должны быть отсортированы по ключу группы.

Если ваши данные и загрузчики удовлетворяют этим условиям, используйте клаузу ‘collected’, чтобы выполнить оптимизированную версию GROUP; операция будет выполнена на стороне карты и избежит выполнения фазы reduce.

'merge'

Используйте клаузу ‘merge’ с операцией COGROUP (работает только с двумя или более отношениями).

Применяются следующие условия:

  • Другие операции не могут выполняться между операторами LOAD и COGROUP.

  • Данные должны быть отсортированы по ключу COGROUP для всех таблиц в порядке возрастания (ASC).

  • NULL считаются меньше всего. Если данные содержат нулевые ключи, они должны идти перед всем остальным.

  • Левый загрузчик должен реализовывать интерфейс {CollectableLoader}, а также интерфейс {OrderedLoadFunc}.

  • Все остальные загрузчики должны реализовывать интерфейс IndexableLoadFunc.

  • Информация о типе должна быть предоставлена в схеме для всех загрузчиков.

Если ваши данные и загрузчики удовлетворяют этим условиям, используйте клаузу ‘merge’, чтобы выполнить оптимизированную версию COGROUP; операция будет выполнена на стороне карты и избежит выполнения фазы reduce.

PARTITION BY partitioner

Используйте эту функцию для указания разделителя Hadoop. Разделитель управляет разделением ключей промежуточных результатов на стороне карты.

  • Подробную информацию см. на странице http://hadoop.apache.org/docs/current/api/org/apache/hadoop/mapred/Partitioner.html

  • Использование см. в Примере: PARTITION BY

PARALLEL n

Увеличьте параллелизм задания, указав количество задач reduce, n.

Дополнительную информацию см. в Использование параллельных функций.

Использование

Оператор GROUP объединяет кортежи, имеющие одинаковый ключ группы (ключевое поле). Ключевое поле будет кортежем, если ключ группы имеет более одного поля, в противном случае он будет того же типа, что и ключ группы. Результатом операции GROUP является отношение, которое включает один кортеж на группу. Этот кортеж содержит два поля:

  • Первое поле называется «группа» (не путайте с оператором GROUP) и имеет тот же тип, что и ключ группы.

  • Второе поле принимает имя исходного отношения и имеет тип пакет.

  • Имена обоих полей генерируются системой, как показано в примере ниже.

Обратите внимание на следующее в отношении операторов GROUP/COGROUP и JOIN:

  • Операторы GROUP и JOIN выполняют похожие функции. GROUP создаёт вложенный набор выходных кортежей, а JOIN — плоский набор выходных кортежей.

  • Операторы GROUP/COGROUP и JOIN обрабатывают нулевые значения по-разному (см. Нулевые значения и операторы GROUP/COGROUP).

Пример

Предположим, у нас есть отношение A.

A = load 'student' AS (name:chararray,age:int,gpa:float);

DESCRIBE A;
A: {name: chararray,age: int,gpa: float}

DUMP A;
(John,18,4.0F)
(Mary,19,3.8F)
(Bill,20,3.9F)
(Joe,18,3.8F)

Теперь, предположим, мы сгруппировали отношение A по полю «возраст», чтобы получить отношение B. Мы можем использовать операторы DESCRIBE и ILLUSTRATE для изучения структуры отношения B. Отношение B имеет два поля. Первое поле называется «группа» и имеет тип int, такой же, как поле «возраст» в отношении A. Второе поле называется «A» после отношения A и имеет тип пакет.

B = GROUP A BY age;

DESCRIBE B;
B: {group: int, A: {name: chararray,age: int,gpa: float}}

ILLUSTRATE B;
etc ... 
----------------------------------------------------------------------
| B     | group: int | A: bag({name: chararray,age: int,gpa: float}) |
----------------------------------------------------------------------
|       | 18         | {(John, 18, 4.0), (Joe, 18, 3.8)}             |
|       | 20         | {(Bill, 20, 3.9)}                             |
----------------------------------------------------------------------

DUMP B;
(18,{(John,18,4.0F),(Joe,18,3.8F)})
(19,{(Mary,19,3.8F)})
(20,{(Bill,20,3.9F)})

Далее, как показано в этих операторах FOREACH, мы можем ссылаться на поля в отношении B по именам «группа» и «A» или по позиционной записи.

C = FOREACH B GENERATE group, COUNT(A);

DUMP C;
(18,2L)
(19,1L)
(20,1L)

C = FOREACH B GENERATE $0, $1.name;

DUMP C;
(18,{(John),(Joe)})
(19,{(Mary)})
(20,{(Bill)})

Пример

Предположим, у нас есть отношение A.

A = LOAD 'data' as (f1:chararray, f2:int, f3:int);

DUMP A;
(r1,1,2)
(r2,2,1)
(r3,2,8)
(r4,4,4)

В этом примере кортежи сгруппированы с использованием выражения f2*f3.

X = GROUP A BY f2*f3;

DUMP X;
(2,{(r1,1,2),(r2,2,1)})
(16,{(r3,2,8),(r4,4,4)})

Пример

Предположим, у нас есть две реляции, A и B.

A = LOAD 'data1' AS (owner:chararray,pet:chararray);

DUMP A;
(Alice,turtle)
(Alice,goldfish)
(Alice,cat)
(Bob,dog)
(Bob,cat)

B = LOAD 'data2' AS (friend1:chararray,friend2:chararray);

DUMP B;
(Cindy,Alice)
(Mark,Alice)
(Paul,Bob)
(Paul,Jane)

В этом примере кортежи объединяются с использованием поля «owner» из реляции A и поля «friend2» из реляции B в качестве ключевых полей. Оператор DESCRIBE показывает схему реляции X, которая имеет три поля: «group», «A» и «B» (см. оператор GROUP для получения информации о названиях полей).

X = COGROUP A BY owner, B BY friend2;

DESCRIBE X;
X: {group: chararray,A: {owner: chararray,pet: chararray},B: {friend1: chararray,friend2: chararray}}

Реляция X выглядит так. Кортеж создается для каждого уникального значения ключевого поля. Кортеж включает ключевое поле и два мешка. Первый мешок содержит кортежи из первой реляции с соответствующим ключевым полем. Второй мешок содержит кортежи из второй реляции с соответствующим ключевым полем. Если кортежи, соответствующие ключевому полю, отсутствуют, мешок пуст.

(Alice,{(Alice,turtle),(Alice,goldfish),(Alice,cat)},{(Cindy,Alice),(Mark,Alice)})
(Bob,{(Bob,dog),(Bob,cat)},{(Paul,Bob)})
(Jane,{},{(Paul,Jane)})

Пример

Этот пример демонстрирует группировку с использованием нескольких ключей.

 A = LOAD 'allresults' USING PigStorage() AS (tcid:int, tpid:int, date:chararray, result:chararray, tsid:int, tag:chararray);
 B = GROUP A BY (tcid, tpid); 

Пример: PARTITION BY

Для использования Hadoop Partitioner добавьте клаузу PARTITION BY к соответствующему оператору:

A = LOAD 'input_data'; 
B = GROUP A BY $0 PARTITION BY org.apache.pig.test.utils.SimpleCustomPartitioner PARALLEL 2;

Вот код для SimpleCustomPartitioner:

public class SimpleCustomPartitioner extends Partitioner <PigNullableWritable, Writable> { 
     //@Override 
    public int getPartition(PigNullableWritable key, Writable value, int numPartitions) { 
        if(key.getValueAsPigType() instanceof Integer) { 
            int ret = (((Integer)key.getValueAsPigType()).intValue() % numPartitions); 
            return ret; 
       } 
       else { 
            return (key.hashCode()) % numPartitions; 
        } 
    } 
}

IMPORT

См. IMPORT (макросы)

JOIN (внутреннее)

Выполняет внутреннее объединение двух или более реляций на основе общих значений полей.

Синтаксис

alias = JOIN alias BY {expression|'('expression [, expression …]')'} (, alias BY {expression|'('expression [, expression …]')'} …) [USING 'replicated' | 'skewed' | 'merge' | 'merge-sparse'] [PARTITION BY partitioner] [PARALLEL n];

Термины

alias

Имя реляции.

BY

Ключевое слово

expression

Выражение поля.

Пример: X = JOIN A BY fieldA, B BY fieldB, C BY fieldC;

USING

Ключевое слово

'replicated'

Используется для выполнения реплицированных объединений (см. Реплицированные Объединения).

'skewed'

Используется для выполнения смещённых объединений (см. Смещённые Объединения).

'merge'

Используется для выполнения объединений слиянием (см. Объединения Слиянием).

'merge-sparse'

Используется для выполнения объединений слиянием-разреженными (см. Объединения Слиянием-Разреженными).

PARTITION BY partitioner

Используйте эту функцию для указания Hadoop Partitioner. Partitioner контролирует распределение ключей промежуточных результатов map-этапов.

  • Для получения подробной информации см. http://hadoop.apache.org/docs/current/api/org/apache/hadoop/mapred/Partitioner.html

  • Для использования см. Пример: PARTITION BY

Эта функция НЕ может быть использована со смещёнными объединениями.

PARALLEL n

Увеличьте параллелизм задачи, указав количество reduce задач, n.

Для получения дополнительной информации, см. Использование Параллельных Функций.

Использование

Используйте оператор JOIN для выполнения внутреннего, эквисоединения двух или более реляций на основе общих значений полей. Внутренние соединения игнорируют нулевые ключи, поэтому имеет смысл отфильтровать их перед соединением.

Обратите внимание на следующее в отношении операторов GROUP/COGROUP и JOIN:

  • Операторы GROUP и JOIN выполняют схожие функции. GROUP создаёт вложенный набор выходных кортежей, а JOIN — плоский набор выходных кортежей.

  • Операторы GROUP/COGROUP и JOIN обрабатывают нулевые значения по-разному (см. Нули и оператор JOIN).

Самосоединения

Для выполнения самосоединений в Pig загрузите одни и те же данные несколько раз под разными псевдонимами, чтобы избежать конфликтов имён.

В этом примере одни и те же данные загружаются дважды с использованием псевдонимов A и B.

grunt> A = load 'mydata';
grunt> B = load 'mydata';
grunt> C = join A by $0, B by $0;
grunt> explain C;

Пример

Предположим, у нас есть реляции A и B.

A = LOAD 'data1' AS (a1:int,a2:int,a3:int);

DUMP A;
(1,2,3)
(4,2,1)
(8,3,4)
(4,3,3)
(7,2,5)
(8,4,3)

B = LOAD 'data2' AS (b1:int,b2:int);

DUMP B;
(2,4)
(8,9)
(1,3)
(2,7)
(2,9)
(4,6)
(4,9)

В этом примере реляции A и B объединяются по их первым полям.

X = JOIN A BY a1, B BY b1;

DUMP X;
(1,2,3,1,3)
(4,2,1,4,6)
(4,3,3,4,6)
(4,2,1,4,9)
(4,3,3,4,9)
(8,3,4,8,9)
(8,4,3,8,9)

JOIN (внешнее)

Выполняет внешнее объединение двух реляций на основе общих значений полей.

Синтаксис

alias = JOIN left-alias BY left-alias-column [LEFT|RIGHT|FULL] [OUTER], right-alias BY right-alias-column [USING 'replicated' | 'skewed' | 'merge'] [PARTITION BY partitioner] [PARALLEL n];

Термины

alias

Имя реляции. Применимо к alias, left-alias и right-alias.

alias-column

Имя столбца соединения для соответствующей реляции. Применимо к left-alias-column и right-alias-column.

BY

Ключевое слово

LEFT

Левое внешнее соединение.

RIGHT

Правое внешнее соединение.

FULL

Полное внешнее соединение.

OUTER

(Необязательно) Ключевое слово

USING

Ключевое слово

'replicated'

Используется для выполнения реплицированных соединений (см. Реплицированные Объединения).

Только левое внешнее соединение поддерживается для реплицированных соединений.

'skewed'

Используется для выполнения смещённых соединений (см. Смещённые Объединения).

'merge'

Используется для выполнения объединений слиянием (см. Объединения Слиянием).

PARTITION BY partitioner

Используйте эту функцию для указания Hadoop Partitioner. Partitioner контролирует распределение ключей промежуточных результатов map-этапов.

  • Для получения подробной информации см. http://hadoop.apache.org/docs/current/api/org/apache/hadoop/mapred/Partitioner.html

  • Для использования см. Пример: PARTITION BY

Эта функция НЕ может быть использована со смещёнными объединениями.

PARALLEL n

Увеличьте параллелизм задачи, указав количество reduce задач, n.

Для получения дополнительной информации, см. Использование Параллельных Функций.

Использование

Используйте оператор JOIN с соответствующими ключевыми словами для выполнения левого, правого или полного внешних объединений. Ключевое слово OUTER необязательно для внешних соединений; ключевые слова LEFT, RIGHT и FULL подразумевают левое внешнее, правое внешнее и полное внешнее соединение соответственно, когда OUTER опущено. Синтаксис Pig Latin тесно придерживается стандарта SQL.

Обратите внимание на следующее:

  • Внешние объединения будут работать только при условии, что реляции, которые должны производить null-значения (в случае несоответствующих ключей), имеют схемы.

  • Внешние объединения будут работать только для двусторонних соединений; чтобы выполнить многостороннее внешнее соединение, вам нужно выполнить несколько двусторонних внешних операторов соединения.

Примеры

В этом примере показано левое внешнее соединение.

A = LOAD 'a.txt' AS (n:chararray, a:int); 
B = LOAD 'b.txt' AS (n:chararray, m:chararray);
C = JOIN A by $0 LEFT OUTER, B BY $0;

В этом примере показано полное внешнее соединение.

A = LOAD 'a.txt' AS (n:chararray, a:int); 
B = LOAD 'b.txt' AS (n:chararray, m:chararray);
C = JOIN A BY $0 FULL, B BY $0;

В этом примере показано реплицированное левое внешнее соединение.

A = LOAD 'large';
B = LOAD 'tiny';
C= JOIN A BY $0 LEFT, B BY $0 USING 'replicated';

В этом примере показано смещённое полное внешнее соединение.

A = LOAD 'studenttab' as (name, age, gpa);
B = LOAD 'votertab' as (name, age, registration, contribution);
C = JOIN A BY name FULL, B BY name USING 'skewed';

LIMIT

Ограничивает количество выходных кортежей.

Синтаксис

alias = LIMIT alias n;

Термины

alias

Имя реляции.

n

Количество выходных кортежей, либо:

  • константа (например, 3)
  • скаляр, используемый в выражении (например, c.sum/100)

Примечание: выражение может состоять из констант или скаляров; оно не может содержать никаких столбцов из входной реляции.

Примечание: использование скаляра вместо константы в LIMIT автоматически отключает большинство оптимизаций (выполняется только push-before-foreach).

Использование

Используйте оператор LIMIT для ограничения количества выходных кортежей.

Если заданное количество выходных кортежей равно или превышает количество кортежей в реляции, возвращаются все кортежи реляции.

Если заданное количество выходных кортежей меньше количества кортежей в реляции, возвращаются n кортежей. Нет гарантии, какие именно n кортежей будут возвращены, и эти кортежи могут меняться от одного выполнения к другому. Конкретный набор кортежей можно запросить с помощью оператора ORDER, за которым следует LIMIT.

Примечание: оператор LIMIT позволяет Pig избежать обработки всех кортежей в реляции. В большинстве случаев запрос, использующий LIMIT, будет выполняться более эффективно, чем идентичный запрос без LIMIT. Всегда рекомендуется использовать limit, если это возможно.

Примеры

В этом примере ограничение выражено как скаляр.

a = load 'a.txt';
b = group a all;
c = foreach b generate COUNT(a) as sum;
d = order a by $0;
e = limit d c.sum/100;

Предположим, у нас есть реляция A.

A = LOAD 'data' AS (a1:int,a2:int,a3:int);

DUMP A;
(1,2,3)
(4,2,1)
(8,3,4)
(4,3,3)
(7,2,5)
(8,4,3)

В этом примере вывод ограничен тремя кортежами. Обратите внимание, что нет гарантии, какие именно три кортежа будут выведены.

X = LIMIT A 3;

DUMP X;
(1,2,3)
(4,3,3)
(7,2,5)

В этом примере оператор ORDER используется для упорядочивания кортежей, а оператор LIMIT используется для вывода первых трёх кортежей.

B = ORDER A BY f1 DESC, f2 ASC;

DUMP B;
(8,3,4) 
(8,4,3) 
(7,2,5) 
(4,2,1)
(4,3,3)
(1,2,3)

X = LIMIT B 3;

DUMP X;
(8,3,4)
(8,4,3) 
(7,2,5) 

LOAD

Загружает данные из файловой системы.

Синтаксис

LOAD 'data' [USING function] [AS schema];

Термины

'data'

Имя файла или каталога в одинарных кавычках.

Если вы укажете имя каталога, все файлы в этом каталоге будут загружены.

Вы можете использовать Hadoop globing для указания файлов на уровне файла или каталога (см. Hadoop globStatus для получения подробной информации о синтаксисе globing).

Примечание: Pig использует Hadoop globbing, поэтому функциональность идентична. Однако, когда вы запускаете команду из командной строки с помощью команды Hadoop fs (а не оператора Pig LOAD), оболочка Unix может выполнить некоторые подстановки; это может изменить результат, создав впечатление, что globbing работает по-разному для Pig и Hadoop. Например:

  • Это работает
    hadoop fs -ls /mydata/20110423{00,01,02,03,04,05,06,07,08,09,{10..23}}00//part
  • Это не работает
    LOAD '/mydata/20110423{00,01,02,03,04,05,06,07,08,09,{10..23}}00//part '

USING

Ключевое слово.

Если предложение USING опущено, используется функция по умолчанию PigStorage.

function

Функция загрузки.

  • Вы можете использовать встроенную функцию (см. Функции загрузки/хранения). PigStorage является функцией загрузки по умолчанию и не требует указания (просто опустите предложение USING).

  • Вы можете написать свою собственную функцию загрузки, если ваши данные находятся в формате, который не может быть обработан встроенными функциями (см. Пользовательские функции).

AS

Ключевое слово.

schema

Схема с использованием ключевого слова AS, заключённая в скобки (см. Схемы).

Загрузчик создаёт данные указанного в схеме типа. Если данные не соответствуют схеме, в зависимости от загрузчика, будет сгенерировано либо значение NULL, либо ошибка.

Примечание: для повышения производительности загрузчик может не сразу преобразовать данные в указанный формат; однако вы всё равно можете работать с данными, предполагая указанный тип.

Использование

Используйте оператор LOAD для загрузки данных из файловой системы.

Примеры

Предположим, что у нас есть файл данных под названием myfile.txt. Поля разделены табуляцией. Записи разделены символами новой строки.

1 2 3
4 2 1
8 3 4

В этом примере функция загрузки по умолчанию, PigStorage, загружает данные из myfile.txt для создания отношения A. Два оператора LOAD эквивалентны. Обратите внимание, что поскольку схема не указана, поля не имеют имён, и все поля по умолчанию имеют тип bytearray.

A = LOAD 'myfile.txt';

A = LOAD 'myfile.txt' USING PigStorage('\t');

DUMP A;
(1,2,3)
(4,2,1)
(8,3,4)

В этом примере схема указана с использованием ключевого слова AS. Два оператора LOAD эквивалентны. Вы можете использовать операторы DESCRIBE и ILLUSTRATE для просмотра схемы.

A = LOAD 'myfile.txt' AS (f1:int, f2:int, f3:int);

A = LOAD 'myfile.txt' USING PigStorage('\t') AS (f1:int, f2:int, f3:int);

DESCRIBE A;
a: {f1: int,f2: int,f3: int}

ILLUSTRATE A;
---------------------------------------------------------
| a     | f1: bytearray | f2: bytearray | f3: bytearray |
---------------------------------------------------------
|       | 4             | 2             | 1             |
---------------------------------------------------------

---------------------------------------
| a     | f1: int | f2: int | f3: int |
---------------------------------------
|       | 4       | 2       | 1       |
---------------------------------------

Примеры указания более сложных схем для использования с оператором LOAD см. в разделах Схемы для сложных типов данных и Схемы для нескольких типов.

MAPREDUCE

Выполняет собственные задачи MapReduce внутри скрипта Pig.

Синтаксис

alias1 = MAPREDUCE 'mr.jar' STORE alias2 INTO 'inputLocation' USING storeFunc LOAD 'outputLocation' USING loadFunc AS schema [`params, ... `];

Термины

alias1, alias2

Имена отношений.

mr.jar

Файл jar MapReduce (в одинарных кавычках).

Вы можете указать любой файл jar MapReduce, который можно запустить с помощью команды hadoop jar mymr.jar params.

Значения для inputLocation и outputLocation могут быть переданы в params.

STORE ... INTO ... USING

См. STORE

Хранение alias2 в inputLocation с помощью storeFunc, который затем используется задачей MapReduce для чтения данных.

LOAD ... USING ... AS

См. LOAD

После выполнения задачи MapReduce mr.jar, загрузить обратно данные из outputLocation в alias1 с помощью loadFunc как схемы.

`params, ...`

Дополнительные параметры, необходимые для задачи mapreduce (в обратных кавычках).

Использование

Используйте оператор MAPREDUCE для запуска собственных задач MapReduce изнутри скрипта Pig.

Пути ввода и вывода для программы MapReduce передаются Pig с помощью предложений STORE/LOAD. Однако Pig не передает эту информацию (и не требует, чтобы она была передана) программе MapReduce. Если вы хотите передать пути ввода и вывода программе MapReduce, вы можете использовать предложение params или закодировать пути в программе MapReduce.

Пример

В этом примере показано, как запустить программу MapReduce wordcount из Pig. Обратите внимание, что файлы, указанные как пути ввода и вывода в операторе MAPREDUCE, не будут автоматически удалены Pig. Вам потребуется удалить их вручную.

A = LOAD 'WordcountInput.txt';
B = MAPREDUCE 'wordcount.jar' STORE A INTO 'inputDir' LOAD 'outputDir' 
    AS (word:chararray, count: int) `org.myorg.WordCount inputDir outputDir`;

ORDER BY

Сортирует отношение на основе одного или нескольких полей.

Синтаксис

alias = ORDER alias BY { * [ASC|DESC] | field_alias [ASC|DESC] [, field_alias [ASC|DESC] …] } [PARALLEL n];

Термины

alias

Имя отношения.

*

Обозначение кортежа.

field_alias

Поле в отношении. Поле должно быть простого типа.

ASC

Сортировка по возрастанию.

DESC

Сортировка по убыванию.

PARALLEL n

Увеличивает параллелизм задачи, указав количество задач reduce, n.

Дополнительную информацию см. в Использование функций параллелизма.

Использование

Примечание: ORDER BY не является стабильным; если несколько записей имеют одинаковый ключ ORDER BY, порядок, в котором эти записи возвращаются, не определён и не гарантируется, что он будет одинаковым при каждом запуске.

В Pig отношения не упорядочены (см. Отношения, множества, кортежи, поля):

  • Если вы сортируете отношение A для создания отношения X (X = ORDER A BY * DESC;), отношения A и X всё ещё содержат те же данные.

  • Если вы извлекаете отношение X (DUMP X;), данные гарантированно будут в указанном вами порядке (по убыванию).

  • Однако, если вы далее обрабатываете отношение X (Y = FILTER X BY $0 > 1;), нет гарантии, что данные будут обрабатываться в первоначально указанном порядке (по убыванию).

Pig в настоящее время поддерживает сортировку по полям с простыми типами или по обозначению кортежа (*). Вы не можете сортировать по полям со сложными типами или по выражениям.

A = LOAD 'mydata' AS (x: int, y: map[]);     
B = ORDER A BY x; -- this is allowed because x is a simple type
B = ORDER A BY y; -- this is not allowed because y is a complex type
B = ORDER A BY y#'id'; -- this is not allowed because y#'id' is an expression

Примеры

Предположим, что у нас есть отношение A.

A = LOAD 'data' AS (a1:int,a2:int,a3:int);

DUMP A;
(1,2,3)
(4,2,1)
(8,3,4)
(4,3,3)
(7,2,5)
(8,4,3)

В этом примере отношение A сортируется по третьему полю, f3, в порядке убывания. Обратите внимание, что порядок трёх кортежей, заканчивающихся на 3, может отличаться.

X = ORDER A BY a3 DESC;

DUMP X;
(7,2,5)
(8,3,4)
(1,2,3)
(4,3,3)
(8,4,3)
(4,2,1)

RANK

Возвращает каждый кортеж с рангом в пределах отношения.

Синтаксис

alias = RANK alias [ BY { * [ASC|DESC] | field_alias [ASC|DESC] [, field_alias [ASC|DESC] …] } [DENSE] ];

Термины

alias

Имя отношения.

*

Обозначение кортежа.

field_alias

Поле в отношении. Поле должно быть простого типа.

ASC

Сортировка по возрастанию.

DESC

Сортировка по убыванию.

DENSE

Без пробелов в значениях ранжирования.

Использование

При отсутствии поля для сортировки оператор RANK просто добавляет последовательное значение к каждому кортежу.

В противном случае оператор RANK использует каждое поле (или набор полей) для сортировки отношения. Ранг кортежа равен единице плюс количеству различных значений ранга, предшествующих ему. Если два или более кортежа совпадают по значениям сортировочного поля, им будет присвоен один и тот же ранг.

ПРИМЕЧАНИЕ: При использовании опции DENSE, совпадения не приводят к пропускам в значениях ранжирования.

Примеры

Предположим, что у нас есть отношение A.

A = load 'data' AS (f1:chararray,f2:int,f3:chararray);
   
DUMP A;
(David,1,N)
(Tete,2,N)
(Ranjit,3,M)
(Ranjit,3,P)
(David,4,Q)
(David,4,Q)
(Jillian,8,Q)
(JaePak,7,Q)
(Michael,8,T)
(Jillian,8,Q)
(Jose,10,V)
            

В этом примере оператор RANK не изменяет порядок отношения и просто добавляет к каждому кортежу последовательное значение.

B = rank A;

dump B;
(1,David,1,N)
(2,Tete,2,N)
(3,Ranjit,3,M)
(4,Ranjit,3,P)
(5,David,4,Q)
(6,David,4,Q)
(7,Jillian,8,Q)
(8,JaePak,7,Q)
(9,Michael,8,T)
(10,Jillian,8,Q)
(11,Jose,10,V)
            

В этом примере оператор RANK работает с полями f1 и f2, и каждое из них с разным порядком сортировки. RANK сортирует отношение по этим полям и добавляет значение ранга к каждому кортежу. В противном случае оператор RANK использует каждое поле (или набор полей) для сортировки отношения. Ранг кортежа равен единице плюс количеству различных значений ранга, предшествующих ему. Если два или более кортежа совпадают по значениям сортировочного поля, им будет присвоен один и тот же ранг.

C = rank A by f1 DESC, f2 ASC;
                                
dump C;
(1,Tete,2,N)
(2,Ranjit,3,M)
(2,Ranjit,3,P)
(4,Michael,8,T)
(5,Jose,10,V)
(6,Jillian,8,Q)
(6,Jillian,8,Q)
(8,JaePak,7,Q)
(9,David,1,N)
(10,David,4,Q)
(10,David,4,Q)                
            

Тот же пример, что и ранее, но DENSE. В этом случае нет пробелов в значениях ранжирования.

C = rank A by f1 DESC, f2 ASC DENSE;

dump C;
(1,Tete,2,N)
(2,Ranjit,3,M)
(2,Ranjit,3,P)
(3,Michael,8,T)
(4,Jose,10,V)
(5,Jillian,8,Q)
(5,Jillian,8,Q)
(6,JaePak,7,Q)
(7,David,1,N)
(8,David,4,Q)
(8,David,4,Q)
            

SAMPLE

Выбирает случайную выборку данных на основе заданного размера выборки.

Синтаксис

SAMPLE alias size;

Термины

псевдоним

Имя отношения.

размер

Размер выборки, либо

  • константа, диапазон от 0 до 1 (например, введите 0,1 для 10 %)
  • скаляр, используемый в выражении

Примечание: выражение может состоять из констант или скаляров; оно не может содержать столбцы из входного отношения.

Использование

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

Пример

В этом примере отношение X будет содержать 1% данных из отношения A.

A = LOAD 'data' AS (f1:int,f2:int,f3:int);

X = SAMPLE A 0.01;

В этом примере используется скалярное выражение (в результате будет выбрано примерно 1000 записей из входных данных).

a = load 'a.txt';
b = group a all;
c = foreach b generate COUNT(a) as num_rows;
e = sample a 1000/c.num_rows;

SPLIT

Разделяет отношение на два или более отношений.

Синтаксис

SPLIT псевдоним INTO псевдоним IF выражение, псевдоним IF выражение [, псевдоним IF выражение …] [, псевдоним OTHERWISE];

Термины

псевдоним

Имя отношения.

INTO

Необходимый ключевой запрос.

IF

Необходимый ключевой запрос.

выражение

Выражение.

OTHERWISE

Необязательный ключевой запрос. Обозначает отношение по умолчанию.

Использование

Используйте оператор SPLIT для разделения содержимого отношения на два или более отношений на основе некоторого выражения. В зависимости от условий, указанных в выражении:

  • Один кортеж может быть назначен более чем одному отношению.

  • Один кортеж может не быть назначен ни одному отношению.

Пример

В этом примере отношение A разделено на три отношения: X, Y и Z.

A = LOAD 'data' AS (f1:int,f2:int,f3:int);

DUMP A;                
(1,2,3)
(4,5,6)
(7,8,9)        

SPLIT A INTO X IF f1<7, Y IF f2==5, Z IF (f3<6 OR f3>6);

DUMP X;
(1,2,3)
(4,5,6)

DUMP Y;
(4,5,6)

DUMP Z;
(1,2,3)
(7,8,9)

Пример

В этом примере операторы SPLIT и FILTER по существу эквивалентны. Однако, поскольку SPLIT реализован как «разделение потока данных, а затем применение фильтров», оператор SPLIT более ресурсоемкий, чем оператор FILTER, потому что Pig должен отфильтровать и сохранить два потока данных.

SPLIT input_var INTO output_var IF (field1 is not null), ignored_var IF (field1 is null);  
-- where ignored_var is not used elsewhere
   
output_var = FILTER input_var BY (field1 is not null);
   

STORE

Сохраняет результаты в файловой системе.

Синтаксис

STORE псевдоним INTO 'директория' [USING функция];

Термины

псевдоним

Имя отношения.

INTO

Необходимый ключевой запрос.

'директория'

Имя каталога хранения в кавычках. Если каталог уже существует, операция STORE завершится неудачей.

В этот каталог записываются выходные файлы данных с именами part-nnnnn.

USING

Ключевой запрос. Используйте эту часть для наименования функции хранения.

Если опустить USING, будет использоваться функция хранения PigStorage по умолчанию.

функция

Функция хранения.

  • Можно использовать встроенную функцию (см. Функции загрузки/хранения). PigStorage — это функция хранения по умолчанию, её не нужно указывать (просто опустите USING).

  • Можно написать собственную функцию хранения, если данные находятся в формате, который не поддерживается встроенными функциями (см. Пользовательские функции).

Использование

Используйте оператор STORE для выполнения (выполнения) инструкций Pig Latin и сохранения (сохранения) результатов в файловой системе. Используйте STORE для производственных скриптов и обработки в пакетном режиме.

Примечание: для отладки скриптов во время разработки можно использовать DUMP для проверки промежуточных результатов.

Примеры

В этом примере данные сохраняются с помощью PigStorage и символа звездочки (*) в качестве разделителя полей.

A = LOAD 'data' AS (a1:int,a2:int,a3:int);

DUMP A;
(1,2,3)
(4,2,1)
(8,3,4)
(4,3,3)
(7,2,5)
(8,4,3)

STORE A INTO 'myoutput' USING PigStorage ('*');

CAT myoutput;
1*2*3
4*2*1
8*3*4
4*3*3
7*2*5
8*4*3

В этом примере используется функция CONCAT для форматирования данных перед сохранением.

A = LOAD 'data' AS (a1:int,a2:int,a3:int);

DUMP A;
(1,2,3)
(4,2,1)
(8,3,4)
(4,3,3)
(7,2,5)
(8,4,3)

B = FOREACH A GENERATE CONCAT('a:',(chararray)f1), CONCAT('b:',(chararray)f2), CONCAT('c:',(chararray)f3);

DUMP B;
(a:1,b:2,c:3)
(a:4,b:2,c:1)
(a:8,b:3,c:4)
(a:4,b:3,c:3)
(a:7,b:2,c:5)
(a:8,b:4,c:3)

STORE B INTO 'myoutput' using PigStorage(',');

CAT myoutput;
a:1,b:2,c:3
a:4,b:2,c:1
a:8,b:3,c:4
a:4,b:3,c:3
a:7,b:2,c:5
a:8,b:4,c:3

STREAM

Отправляет данные во внешний скрипт или программу.

Синтаксис

псевдоним = STREAM псевдоним [, псевдоним …] THROUGH {`команда` | псевдоним_команды } [AS схема] ;

Термины

псевдоним

Имя отношения.

THROUGH

Ключевое слово.

`команда`

Команда, включая аргументы, заключённые в обратные кавычки (любая команда, которую можно выполнить).

псевдоним_команды

Имя команды, созданной с помощью оператора DEFINE (см. DEFINE (UDFs, streaming) для дополнительных примеров потоковой передачи).

AS

Ключевое слово.

схема

Схема, использующая ключевое слово AS, заключённая в скобки (см. Схемы).

Использование

Используйте оператор STREAM для передачи данных через внешний скрипт или программу. В одном скрипте Pig могут присутствовать несколько операторов stream. Операторы stream могут быть расположены рядом или между другими операциями.

При использовании с командой оператор stream может выглядеть следующим образом:

A = LOAD 'data';

B = STREAM A THROUGH `stream.pl -n 5`;

При использовании с псевдонимом_команды оператор stream может выглядеть так, где mycmd — определённый псевдоним.

A = LOAD 'data';

DEFINE mycmd `stream.pl –n 5`;

B = STREAM A THROUGH mycmd;

О гарантиях данных

Гарантии данных определяются на основе позиции оператора stream в скрипте Pig.

  • Неупорядоченные данные — Нет гарантий порядка, в котором данные передаются приложению для потоковой обработки.

  • Сгруппированные данные — Данные для одного и того же сгруппированного ключа гарантированно предоставляются приложению для потоковой обработки непрерывно.

  • Сгруппированные и упорядоченные данные — Данные для одного и того же сгруппированного ключа гарантированно предоставляются приложению для потоковой обработки непрерывно. Кроме того, данные внутри группы гарантированно упорядочены по предоставленному вторичному ключу.

В дополнение к позиции, группировка и упорядочивание данных могут быть определены самими данными. Однако, чтобы воспользоваться их структурой, необходимо знать свойства данных.

Пример: Гарантии данных

В этом примере данные неупорядочены.

A = LOAD 'data';

B = STREAM A THROUGH `stream.pl`;

В этом примере данные сгруппированы.

A = LOAD 'data';

B = GROUP A BY $1;

C = FOREACH B FLATTEN(A);

D = STREAM C THROUGH `stream.pl`;

В этом примере данные сгруппированы и упорядочены.

A = LOAD 'data';

B = GROUP A BY $1;

C = FOREACH B {
      D = ORDER A BY ($3, $4);
      GENERATE D;
}

E = STREAM C THROUGH `stream.pl`;

Пример: Схемы

В этом примере схема указана в операторе STREAM.

X = STREAM A THROUGH `stream.pl` as (f1:int, f2:int, f3:int);

UNION

Вычисляет объединение двух или более отношений.

Синтаксис

псевдоним = UNION [ONSCHEMA] псевдоним, псевдоним [, псевдоним …] [PARALLEL n];

Термины

псевдоним

Имя отношения.

ONSCHEMA

Используйте ONSCHEMA для основы объединения на именованных полях (а не на позиционной нотации). Все входные данные для объединения должны иметь не неизвестную (не NULL) схему.

PARALLEL n

Это применимо только для режима выполнения Tez и не будет работать в режиме Mapreduce. Указание PARALLEL добавит дополнительный шаг reduce, что немного снизит производительность. В данном случае основная цель — управление количеством выходных файлов.

Дополнительную информацию см. в разделе Использование параллельных функций.

Использование

Используйте оператор UNION для объединения содержимого двух или более отношений. Оператор UNION:

  • Не сохраняет порядок кортежей. Как входные, так и выходные отношения интерпретируются как неупорядоченные пакеты кортежей.

  • Не гарантирует (как это делают базы данных), что все кортежи соответствуют одной схеме или что у них одинаковое количество полей. Однако в типичной ситуации это должно быть так; поэтому ответственность пользователя состоит в том, чтобы либо (1) гарантировать, что кортежи в входных отношениях имеют одинаковую схему, либо (2) иметь возможность обрабатывать различные кортежи в выходном отношении.

  • Не удаляет дублирующие кортежи.

Поведение схемы

Поведение схем для UNION (позиционная нотация/типы данных) и UNION ONSCHEMA (именованные поля/типы данных) одинаковое, за исключением случаев, отмеченных в тексте.

Объединение отношений с разными размерами приводит к схеме null (только объединение):

A: (a1:long, a2:long) 
B: (b1:long, b2:long, b3:long) 
A union B: null 

Объединение столбцов с несовместимыми типами приводит к типу bytearray:

A: (a1:long, a2:long) 
B: (b1:(b11:long, b12:long), b2:long) 
A union B: (a1:bytearray, a2:long) 

Объединение столбцов совместимого типа даст тип «escalate». Приоритет:

  • double > float > long > int > bytearray
  • tuple|bag|map|chararray > bytearray
A: (a1:int, a2:bytearray, a3:int) 
B: (b1:float, b2:chararray, b3:bytearray) 
A union B: (a1:float, a2:chararray, a3:int) 

Объединение разных внутренних типов приводит к пустому сложному типу:

A: (a1:(a11:long, a12:int), a2:{(a21:charray, a22:int)}) 
B: (b1:(b11:int, b12:int), b2:{(b21:int, b22:int)}) 
A union B: (a1:(), a2:{()}) 

Псевдоним первого отношения всегда используется как псевдоним поля объединённого отношения.

Пример

В этом примере вычисляется объединение отношений A и B.

A = LOAD 'data' AS (a1:int,a2:int,a3:int);

DUMP A;
(1,2,3)
(4,2,1)

B = LOAD 'data' AS (b1:int,b2:int);

DUMP A;
(2,4)
(8,9)
(1,3)

X = UNION A, B;

DUMP X;
(1,2,3)
(4,2,1)
(2,4)
(8,9)
(1,3)

Пример

Этот пример демонстрирует использование ONSCHEMA.

L1 = LOAD 'f1' USING (a : int, b : float);
DUMP L1;
(11,12.0)
(21,22.0)

L2 = LOAD  'f1' USING (a : long, c : chararray);
DUMP L2;
(11,a)
(12,b)
(13,c)

U = UNION ONSCHEMA L1, L2;
DESCRIBE U ;
U : {a : long, b : float, c : chararray}

DUMP U;
(11,12.0,)
(21,22.0,)
(11,,a)
(12,,b)
(13,,c)

UDF Операции

ОПРЕДЕЛЕНИЕ (UDF, потоковая обработка)

Присваивает псевдоним функции UDF или команде потоковой обработки.

Синтаксис: UDF и потоковая обработка

ОПРЕДЕЛИТЬ псевдоним {функция | [`команда` [вход] [выход] [пересылка] [кеш] [stderr] ] };

Термины

псевдоним

Имя функции UDF или имя команды потоковой обработки (cmd_alias для оператора STREAM).

функция

Для использования с функциями.

Имя функции UDF.

`команда`

Для использования с потоковой обработкой.

Команда, включая аргументы, заключённые в обратные кавычки (любая команда, которую можно выполнить).

Описания разделов (вход, выход, пересылка, кеш, stderr) приведены ниже. Обратите внимание на следующее:

  • Все разделы являются необязательными.
  • Разделы можно указывать в любом порядке (например, stderr может стоять перед входом).
  • Каждый раздел можно указать не более одного раза (например, несколько входов не допускаются).

вход

Для использования с потоковой обработкой.

ВХОД ( {stdin | 'путь'} [Используя сериализатор] [, {stdin | 'путь'} [Используя сериализатор] …] )

Где:

  • ВХОД – Ключевое слово.

  • 'путь' – Путь к файлу, заключенный в одинарные кавычки.

  • Используя – Ключевое слово.

  • сериализатор – PigStreaming — по умолчанию.

выход

Для использования с потоковой обработкой.

ВЫХОД ( {stdout | stderr | 'путь'} [Используя десериализатор] [, {stdout | stderr | 'путь'} [Используя десериализатор] …] )

Где:

  • ВЫХОД – Ключевое слово.

  • 'путь' – Путь к файлу, заключенный в одинарные кавычки.

  • Используя – Ключевое слово.

  • десериализатор – PigStreaming — по умолчанию.

пересылка

Для использования с потоковой обработкой.

ПЕРЕСЫЛАТЬ('путь' [, 'путь' …])

Где:

  • ПЕРЕСЫЛАТЬ – Ключевое слово.

  • 'путь' – Путь к файлу, заключенный в одинарные кавычки.

кеш

Для использования с потоковой обработкой.

КЕШ('путь_к_файлу#имя_файла' [, 'путь_к_файлу#имя_файла' …])

Где:

  • КЕШ – Ключевое слово.

  • 'путь_к_файлу#имя_файла' – Путь/имя файла на распределенной файловой системе, заключенное в одинарные кавычки. Пример: '/mydir/mydata.txt#mydata.txt'

stderr

Для использования с потоковой обработкой.

STDERR( '/каталог') или STDERR( '/каталог' ОГРАНИЧЕНИЕ n)

Где:

  • '/каталог' – Каталог логов, заключённый в одинарные кавычки.
  • (необязательно) ОГРАНИЧЕНИЕ n – порог ошибок, где n — целое значение. Если не указано, порог ошибок неограничен.

Использование

Используйте оператор ОПРЕДЕЛИТЬ, чтобы присвоить имя (псевдоним) функции UDF или команде потоковой обработки.

Используйте ОПРЕДЕЛИТЬ для указания функции UDF, когда:

  • Функция имеет длинное имя пакета, которое вы не хотите включать в скрипт, особенно если вы вызываете функцию несколько раз в этом скрипте.

  • Конструктор функции принимает строковые параметры. Если вам нужно использовать различные параметры конструктора для разных вызовов функции, вам нужно создать несколько определений — по одному для каждого набора параметров.

Используйте ОПРЕДЕЛИТЬ для указания команды потоковой обработки, когда:

  • Спецификация команды потоковой обработки сложная.

  • Спецификация команды потоковой обработки требует дополнительных параметров (вход, выход и т. д.).

Об входе и выходе

Необходима сериализация для преобразования данных из кортежей в формат, который может обрабатываться приложением потоковой обработки. Необходима десериализация для преобразования выходных данных приложения потоковой обработки обратно в кортежи. PigStreaming — это функция сериализации/десериализации по умолчанию.

Потоковая обработка использует тот же формат по умолчанию, что и PigStorage, для сериализации/десериализации данных. Если вы хотите явно указать формат, вы можете сделать это, как показано ниже (см. дополнительные примеры в разделе Примеры: Вход/Выход).

DEFINE CMD `perl PigStreaming.pl - nameMap` input(stdin using PigStreaming(',')) output(stdout using PigStreaming(','));
A = LOAD 'file';
B = STREAM B THROUGH CMD;

Если вам нужен альтернативный формат, вам нужно создать пользовательскую функцию сериализации/десериализации, реализовав следующие интерфейсы.

interface PigToStream {

    /**
     * Given a tuple, produce an array of bytes to be passed to the streaming
     * executable.
     */
    public byte[] serialize(Tuple t) throws IOException;
}

interface StreamToPig {

    /**
     *  Given a byte array from a streaming executable, produce a tuple.
     */
    public Tuple deserialize(byte[]) throws IOException;

    /**
     * This will be called on the front end during planning and not on the back
     * end during execution.
     *
     * @return the {@link LoadCaster} associated with this object.
     * @throws IOException if there is an exception during LoadCaster
     */
    public LoadCaster getLoadCaster() throws IOException;
}
О пересылке

Используйте параметр пересылка, чтобы отправлять бинарные файлы потоковой обработки и связанные с ними файлы (если таковые имеются) с узла клиента на узлы вычислений. Pig не отправляет зависимости автоматически; вы сами должны явно указать все зависимости и убедиться, что на кластере установлено всё необходимое программное обеспечение (например, perl или python). Вспомогательные файлы отправляются в текущую рабочую директорию задачи, и должны быть указаны только относительные пути. Любые предварительно установленные двоичные файлы должны быть указаны в переменной PATH.

Можно указать только файлы, а не каталоги, с помощью параметра пересылка. Один из способов обойти это ограничение — архивировать все зависимости в архивный файл tar, точно отражающий необходимую структуру на узлах вычислений, а затем создать оболочку для своего скрипта, которая будет разархивировать зависимости перед выполнением.

Обратите внимание, что параметр пересылка имеет два компонента: указание источника, предоставленное в разделе пересылка( ), отображает вашу машину; указание команды отображает фактический кластер. Единственная гарантия заключается в том, что отправленные файлы доступны в текущей рабочей директории запущенной задачи и что ваша текущая рабочая директория также находится в переменной окружения PATH.

Отправка файлов по относительным или абсолютным путям не поддерживается, так как у вас может не быть разрешений на чтение/запись/исполнение из произвольных путей на кластерах.

Обратите внимание на следующее:

  • Безопасно отправлять файлы только для их выполнения из текущей рабочей директории задачи на кластере.

    OP = stream IP through 'script';
    or
    DEFINE CMD 'script' ship('/a/b/script');
    OP = stream IP through CMD;
    
  • Отправка файлов по относительным или абсолютным путям не определена и чаще всего завершится неудачей, так как у вас может не быть разрешений на чтение/запись/исполнение из произвольных путей на фактических кластерах.

О кэше

Параметр пересылка подходит для двоичных файлов, jar-файлов и небольших наборов данных. Однако загрузка больших наборов данных во время выполнения для каждого запуска может значительно снизить производительность. Вместо этого используйте параметр кеш для доступа к большим файлам, которые уже перемещены на узлы вычислений и доступны на них. Можно указать только файлы, а не каталоги, с помощью параметра кеш.

О автоматической отправке

Если параметры пересылка и кеш не указаны, Pig попытается автоматически отправить двоичный файл следующим образом:

  • Если первое слово в команде потоковой обработки — perl или python, Pig предполагает, что двоичный файл — это первая необрамлённая строка, которая не начинается с дефиса.

  • В противном случае Pig попытается отправить первую строку из командной строки, если она не из /bin, /usr/bin, /usr/local/bin. Pig определит это путём сканирования пути, если указан абсолютный путь, или выполнив which. Пути можно сделать настраиваемыми с помощью параметра set stream.skippath (можно использовать несколько команд set, чтобы указать более одного пути для пропуска).

Если вы не укажете ОПРЕДЕЛЕНИЕ для данной команды потоковой обработки, автоматическая отправка отключена.

Обратите внимание на следующее:

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

    OP = stream IP through `/a/b/c/script`;
    or 
    OP = stream IP through `perl /a/b/c/script.pl`;
    
  • Pig не будет автоматически отправлять файлы в следующих системных каталогах (это определяется выполнением команды 'which <файл>' ).

    /bin /usr/bin /usr/local/bin /sbin /usr/sbin /usr/local/sbin
    
  • Для автоматической отправки файл должен находиться в PATH. Таким образом, если файл находится в текущей рабочей директории, то текущая рабочая директория должна быть в PATH.

Примеры: Вход/Выход

В этом примере PigStreaming — это функция сериализации/десериализации по умолчанию. Кортежи из отношения A преобразуются в строки, разделённые табуляцией, которые передаются скрипту.

X = STREAM A THROUGH `stream.pl`;

В этом примере PigStreaming используется как функция сериализации/десериализации, но в качестве разделителя используется запятая.

DEFINE Y 'stream.pl' INPUT(stdin USING PigStreaming(',')) OUTPUT (stdout USING PigStreaming(','));

X = STREAM A THROUGH Y;

В этом примере используются пользовательские функции сериализации/десериализации со скриптом.

DEFINE Y 'stream.pl' INPUT(stdin USING MySerializer) OUTPUT (stdout USING MyDeserializer);

X = STREAM A THROUGH Y;

Примеры: Пересылка/Кеш

В этом примере используется пересылка для отправки скрипта на узлы вычислений кластера.

DEFINE Y 'stream.pl' SHIP('/work/stream.pl');

X = STREAM A THROUGH Y;

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

DEFINE Y 'stream.pl data.gz' SHIP('/work/stream.pl') CACHE('/input/data.gz#data.gz');

X = STREAM A THROUGH Y;

Пример: ОПРЕДЕЛЕНИЕ с STREAM

В этом примере определена команда для использования с оператором STREAM.

A = LOAD 'data';

DEFINE mycmd 'stream_cmd –input file.dat';

B = STREAM A through mycmd;

Примеры: Логирование

В этом примере вывод stderr потоковой обработки сохраняется в каталоге _logs/<dir> каталога вывода задачи. Поскольку у задачи может быть несколько приложений потоковой обработки, необходимо убедиться, что используются разные имена каталогов, чтобы избежать конфликтов. Pig хранит до 100 задач на задачу потоковой обработки.

DEFINE Y 'stream.pl' stderr('<dir>' limit 100);

X = STREAM A THROUGH Y;

Примеры: ОПРЕДЕЛЕНИЕ функции

В этом примере определена функция для использования с оператором FOREACH …GENERATE.

REGISTER /src/myfunc.jar

DEFINE myFunc myfunc.MyEvalfunc('foo');

A = LOAD 'students';

B = FOREACH A GENERATE myFunc($0);

РЕГИСТРИРОВАТЬ (jar/скрипт)

Регистрирует JAR-файл, чтобы можно было использовать UDF в нём.

Синтаксис

РЕГИСТРИРОВАТЬ путь;

Термины

путь

Путь к JAR-файлу (требуется полное расположение URI). Не заключайте имя в кавычки.

Использование

Скрипты Pig

Используйте оператор REGISTER внутри скрипта Pig для указания JAR-файла или модуля Python/JavaScript. Pig поддерживает JAR-файлы и модули, хранящиеся в локальных файловых системах, а также в удалённых распределённых файловых системах, таких как HDFS и Amazon S3 (см. Скрипты Pig).

Кроме того, JAR-файлы, хранящиеся в локальных файловых системах, могут быть указаны как шаблон подстановки «*». Pig будет искать соответствующие jar-файлы в локальной файловой системе, либо по относительному пути (относительно вашей рабочей директории), либо по абсолютному пути. Pig возьмёт все JAR-файлы, соответствующие шаблону.

Командная строка

Вы можете зарегистрировать дополнительные файлы (для использования с вашим скриптом Pig) через переменную окружения PIG_OPTS, используя параметр -Dpig.additional.jars.uris. Для получения дополнительной информации см. Пользовательские функции.

Примеры

В этом примере команда REGISTER указывает, что JavaScript-модуль myfunc.js расположен в каталоге /src.

/src $ java -jar pig.jar –

REGISTER /src/myfunc.js;
A = LOAD 'students';
B = FOREACH A GENERATE myfunc.MyEvalFunc($0);

В этом примере дополнительные JAR-файлы регистрируются через переменную окружения PIG_OPTS.

export PIG_OPTS="-Dpig.additional.jars.uris=my.jar,your.jar"

В этом примере регистрируется JAR-файл, хранящийся в HDFS, и локальный JAR-файл.

export PIG_OPTS="-Dpig.additional.jars.uris=hdfs://nn.mydomain.com:9020/myjars/my.jar,file:///home/root/pig/your.jar"

Обратите внимание, что устаревшее свойство pig.additional.jars, использующее двоеточие в качестве разделителя, по-прежнему поддерживается. Однако мы рекомендуем использовать pig.additional.jars.uris, так как двоеточие также используется в схеме URL, и поэтому мы не можем использовать полную схему в списке. В будущих выпусках свойство pig.additional.jar будет устаревшим.

Этот пример показывает, как указать шаблон glob, используя относительный или абсолютный путь.

register /homes/user/pig/myfunc*.jar
register count*.jar
register jars/*.jar

Регистрация артефакта

Вместо того, чтобы вручную определять зависимости, скачивать их и регистрировать каждый JAR с помощью команды register, вы можете указать координаты артефакта, и Pig автоматически загрузит необходимые зависимости, скачает и зарегистрирует их.

Синтаксис

Чтобы загрузить артефакт (и его зависимости), необходимо указать группу, модуль и версию артефакта, следуя приведенному ниже синтаксису. Эта команда загрузит указанный JAR-файл и все его зависимости и загрузит его в путь к классам.

REGISTER ivy://group:module:version?querystring

Термины

group

Группа модуля, к которой относится модуль. Соответствует Maven groupId или Ivy Organization.

module

Имя модуля для загрузки. Соответствует Maven artifactId или Ivy artifact.

version

Версия используемого модуля. Вы можете указать конкретную версию или использовать «+» или «*» для использования последней версии.

querystring

Будет содержать пары ключ-значение, разделенные «&», чтобы помочь нам исключить все или определенные зависимости и т. д.

Использование

Команда Register artifact — это расширение команды register, используемой для регистрации JAR-файла. Помимо регистрации JAR-файла из локальной системы или из HDFS, вы теперь можете указать координаты артефакта, и Pig загрузит артефакт (и его зависимости, если необходимо) из конфигурированного репозитория.

Поддерживаемые параметры в строке запроса
  • Transitive

    Transitive позволяет указать, нужны ли зависимости вместе с регистрируемым JAR-файлом. Установив transitive в false в строке запроса, мы можем сказать Pig, что нужно регистрировать только артефакт без его зависимостей. Это загрузит только указанный артефакт и не загрузит зависимости JAR-файла. Значение по умолчанию для transitive — true.

    Синтаксис

    REGISTER ivy://org:module:version?transitive=false

  • Exclude

    При регистрации артефакта, если вы хотите исключить некоторые зависимости, вы можете указать их с помощью ключа exclude. Предположим, вам нужна определенная версия зависимого JAR-файла, которая не соответствует версии JAR-файла, автоматически загруженной Pig, тогда вы можете исключить такие зависимости, указав список зависимостей, разделенных запятыми, и зарегистрировать зависимый JAR-файл отдельно.

    Синтаксис

    REGISTER ivy://org:module:version?exclude=org:mod,org:mod,...

  • Classifier

    Некоторые зависимости Maven требуют классификаторов для разрешения. Вы можете указать их с помощью ключа classifier.

    Синтаксис

    REGISTER ivy://org:module:version?classifier=value

Другие свойства
  • Необязательное свойство Pig pig.artifacts.download.location может использоваться для настройки расположения, где будут загружаться артефакты. По умолчанию они будут загружены в ~/.groovy/grapes

  • Эта команда может использоваться или может заменить команду register jar везде, где она используется, включая макросы.

  • Поля Group/Organization и Version являются необязательными. В таких случаях вы можете оставить их пустыми.

  • Репозитории могут настраиваться с помощью файла ivysettings. Pig будет искать файл ivysettings.xml в следующих расположениях в указанном порядке: PIG_CONF_DIR > PIG_HOME > Путь к классам

Примеры

  • Регистрация артефакта и всех его зависимостей.

                    -- Both are the same
    REGISTER ivy://org.apache.avro:avro:1.5.1
    REGISTER ivy://org.apache.avro:avro:1.5.1?transitive=true
  • Регистрация артефакта без получения его зависимостей.

                   REGISTER ivy://org.apache.avro:avro:1.5.1?transitive=false
  • Регистрация последнего артефакта.

                    -- Both of the following syntaxes work.
    REGISTER ivy://org.apache.avro:avro:+
    REGISTER ivy://org.apache.avro:avro:*
  • Регистрация артефакта с исключением определенных зависимостей.

                    REGISTER ivy://org.apache.pig:pig:0.10.0?exclude=commons-cli:commons-cli,commons-codec:commons-codec
  • Указание классификатора

                    REGISTER ivy://net.sf.json-lib:json-lib:2.4?classifier=jdk15
  • Регистрация артефакта без группы или организации. Просто пропустите их.

                    REGISTER ivy://:module:

© 2007–2016 Apache Software Foundation
Licensed under the Apache Software License version 2.0.
https://pig.apache.org/docs/r0.16.0/basic.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API