Spec-Zone.ru › Apache Pig 0.14

Основы 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 (UDF, потоковая обработка)
    • 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

-- F

f, F, filter, flatten, float, foreach, full

-- G

generate, group

-- H

help

-- I

if, illustrate, import, inner, input, int, into, is

-- J

join

-- K

kill

-- L

l, L, left, limit, load, long, ls

-- M

map, matches, MAX, MIN, mkdir, mv

-- N

not, null

-- O

onschema, or, order, outer, output

-- P

parallel, pig, PigDump, PigStorage, pwd

-- Q

quit

-- R

register, returns, right, rm, rmf, rollup, run

-- S

sample, set, ship, SIZE, split, stderr, stdin, stdout, store, stream, SUM

-- T

TextLoader, TOKENIZE, through, tuple

-- U

union, using

-- V, W, X, Y, Z

void

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

Имена (псевдонимы) отношений и полей чувствительны к регистру. Имена функций 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

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

name

age

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

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;
    
  • Если схема определена как часть операторного выражения load, функция load попытается применить схему. Если данные не соответствуют схеме, загрузчик сгенерирует значение 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 …

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

Кортеж

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

Синтаксис

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

Термины

( )

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

поле

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

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

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

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

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

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

Пример

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

(John,18,4.0F)

Мешок

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

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

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

Термины

{ }

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

кортеж

Кортеж.

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

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

  • Мешок может содержать дублирующие кортежи.

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

  • Мешок может содержать кортежи с полями разных типов данных. Однако для эффективной обработки мешков схемы кортежей в этих мешках должны быть одинаковыми. Например, если половина кортежей включает поля 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.

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

+ , -, *, /

% модуль

? : 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 с одним отношением записи с нулевым ключом группируются вместе.

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) с несколькими отношениями записи с нулевым ключом из разных отношений считаются различными и группируются отдельно. В примере ниже обратите внимание, что в выходных данных есть два кортежа, соответствующих нулевому ключу: один, содержащий кортежи из отношения 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

'hello world'

bytearray

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

boolean

true/false

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

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

кортеж

(19, 2, 1)

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

пакет

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

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

карта

[ 'name' # 'John', 'ext' # 5555 ]

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

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

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

  • Для указания длинной константы необходимо добавить 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 базовым типом, результатом общего выражения не может быть boolean. Выражения полей являются простейшими общими выражениями.

Схемы

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

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

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

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

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

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

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

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

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

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

  • При выполнении JOIN/COGROUP/CROSS нескольких отношений, если у любого отношения неизвестная схема (или нет определенной схемы, также называется нулевой схемой), схема результирующего отношения будет нулевой.
  • Если вы выполняете FLATTEN на множестве с пустой внутренней схемой, схема результирующего отношения будет нулевой.
  • Если вы выполняете UNION двух отношений с несовместимыми схемами, схема результирующего отношения будет нулевой.
  • Если схема нулевая, 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).

bincond

? :

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

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

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

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

case

CASE WHEN THEN ELSE END

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

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

Оператор Case эквивалентен вложенным операторам bincond.

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

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

Примеры

Предположим, у нас есть таблица А.

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)

В этом примере оператор bincond используется с полями 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, возвращается 'четное'; если равно 1, возвращается 'нечетное'.

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

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

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

bag

tuple

map

int

long

float

double

chararray

bytearray

bag

ошибка

ошибка

ошибка

ещё нет

ещё нет

ещё нет

ещё нет

ошибка

ошибка

tuple

ошибка

ошибка

ещё нет

ещё нет

ещё нет

ещё нет

ошибка

ошибка

map

ошибка

ошибка

ошибка

ошибка

ошибка

ошибка

ошибка

int

int

long

float

double

ошибка

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

long

long

float

double

ошибка

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

float

float

double

ошибка

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

double

double

ошибка

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

chararray

ошибка

ошибка

bytearray

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

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

int

long

bytearray

int

int

long

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

long

long

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

bytearray

ошибка

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

Описание

Оператор

Символ

Примечания

И

and

ИЛИ

or

В

in

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

НЕ

not

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

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

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

Описание

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

от / до

мешок

кортеж

словарь

целое

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

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

двойное

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

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

булево

мешок

ошибка

ошибка

ошибка

ошибка

ошибка

ошибка

ошибка

ошибка

ошибка

кортеж

ошибка

ошибка

ошибка

ошибка

ошибка

ошибка

ошибка

ошибка

ошибка

словарь

ошибка

ошибка

ошибка

ошибка

ошибка

ошибка

ошибка

ошибка

ошибка

целое

ошибка

ошибка

ошибка

да

да

да

да

ошибка

ошибка

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

ошибка

ошибка

ошибка

да

да

да

да

ошибка

ошибка

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

ошибка

ошибка

ошибка

да

да

да

да

ошибка

ошибка

двойное

ошибка

ошибка

ошибка

да

да

да

да

ошибка

ошибка

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

ошибка

ошибка

ошибка

да

да

да

да

ошибка

да

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

да

да

да

да

да

да

да

да

да

булево

ошибка

ошибка

ошибка

ошибка

ошибка

ошибка

ошибка

да

ошибка

Синтаксис

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

Термины

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

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

поле

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

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

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

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

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

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

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

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

  • Приведение типов может привести к потере данных. Например, приведение от длинного целого к целому может привести к отбрасыванию битов.

Примеры

В этом примере целое приводится к типу символьный массив (см. отношение 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. Также, если схема не может быть определена, используется байтовый массив.

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

В этом примере вычисляется процент кликов, принадлежащих конкретному пользователю. Для оператора 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

кортеж

карта

int

long

float

double

chararray

bytearray

boolean

datetime

biginteger

bigdecimal

bag

ошибка

ошибка

ошибка

ошибка

ошибка

ошибка

ошибка

ошибка

ошибка

ошибка

ошибка

ошибка

ошибка

кортеж

boolean

(см. Примечание 1)

ошибка

ошибка

ошибка

ошибка

ошибка

ошибка

ошибка

ошибка

ошибка

ошибка

ошибка

карта

boolean

(см. Примечание 2)

ошибка

ошибка

ошибка

ошибка

ошибка

ошибка

ошибка

ошибка

ошибка

ошибка

int

boolean

boolean

boolean

boolean

ошибка

преобразование в boolean

ошибка

ошибка

ошибка

ошибка

long

boolean

boolean

boolean

ошибка

преобразование в boolean

ошибка

ошибка

ошибка

ошибка

float

boolean

boolean

ошибка

преобразование в boolean

ошибка

ошибка

ошибка

ошибка

double

boolean

ошибка

преобразование в boolean

ошибка

ошибка

ошибка

ошибка

chararray

boolean

преобразование в boolean

ошибка

ошибка

ошибка

ошибка

bytearray

boolean

ошибка

ошибка

ошибка

ошибка

boolean

boolean

ошибка

ошибка

ошибка

datetime

boolean

ошибка

ошибка

biginteger

boolean

ошибка

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)

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

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

error

error

error

error

error

error

error

error

error

error

error

error

map

error

error

error

error

error

error

error

error

error

error

error

int

boolean

boolean

boolean

boolean

error

boolean (bytearray cast as int)

error

error

error

error

long

boolean

boolean

boolean

error

boolean (bytearray cast as long)

error

error

error

error

float

boolean

boolean

error

boolean (bytearray cast as float)

error

error

error

error

double

boolean

error

boolean (bytearray cast as double)

error

error

error

error

chararray

boolean

boolean (bytearray cast as chararray)

error

error

error

error

bytearray

boolean

error

error

error

error

boolean

boolean

error

error

error

datetime

boolean

error

error

biginteger

boolean

error

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#'ключ'

Распаковка карты должна выполняться по ключу (field_name#ключ или $0#ключ). Если оператор решетки применяется к 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 пустого мешка приведет к тому, что строка будет пропущена; вывод не будет сгенерирован. (См. также Удаление NULL перед объединением.)

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

Описание

Оператор

Символ

Примечания

is null

is null

is not 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 expression [, message];

Термины

alias

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

BY

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

expression

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

message

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

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

Используйте 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. Разделитель управляет разбиением ключей промежуточных выходных данных 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

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

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

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

Операция сворачивания

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

Синтаксис

alias = CUBE alias BY { CUBE expression | ROLLUP expression }, [ CUBE expression | ROLLUP expression ] [PARALLEL n];

Термины

alias

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

CUBE

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

BY

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

expression

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

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;

Для примера входного кортежа (car, 2012, midwest, ohio, columbus, 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)}}

Обратите внимание на второй столбец, поле «куб», которое представляет собой набор всех кортежей, принадлежащих к «группе». Обратите также внимание, что атрибут меры «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;

Для примера входного кортежа (car, 2012, midwest, ohio, columbus, 4000) приведенный выше запрос с операцией сворачивания выведет

(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 используются вместе, выходные группы будут декартовым произведением всех групп, сгенерированных операцией куба и сворачивания. Если в операциях куба m измерений, а в операции сворачивания 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;

Для примера входного кортежа (car, 2012, midwest, ohio, columbus, 4000) приведенный выше запрос с операцией куба и сворачивания выведет

(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)}}

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

Поскольку значения NULL используются для представления итогов в операции куба и сворачивания, для того чтобы различать законные значения NULL, которые уже существуют как значения измерений, оператор CUBE преобразует любые значения NULL в измерениях в значение «unknown» перед выполнением операции куба или сворачивания. Например, для CUBE(product,location) с образцом кортежа (car,) выход будет равен

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

DEFINE

См.:

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

DISTINCT

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

Синтаксис

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

Термины

alias

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

PARTITION BY partitioner

Используйте эту функцию, чтобы указать Hadoop 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 expression;

Термины

alias

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

BY

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

expression

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

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

Используйте оператор 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 { block | nested_block };

Термины

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)

Другой пример развёртывания.

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

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

Другой пример развёртывания. Обратите внимание, что для группы '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)

Другой пример развёртывания. Здесь отношения 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-значения считаются меньше любого другого значения. Если данные содержат null-ключи, они должны идти перед другими значениями.

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

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

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

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

PARTITION BY partitioner

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

  • Подробнее см. http://hadoop.apache.org/docs/current/api/org/apache/hadoop/mapred/Partitioner.html

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

PARALLEL n

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

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

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

Оператор GROUP объединяет кортежи, имеющие одинаковый ключ группы (ключевое поле). Ключевое поле будет кортежем, если ключ группы имеет более одного поля, в противном случае он будет того же типа, что и ключ группы. Результатом операции 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 имеет два поля. Первое поле называется «group» и имеет тип 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 по именам «group» и «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 обрабатывают нулевые значения по-разному (см. Nulls и оператор 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 опущен.

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

  • Внешние соединения будут работать только при условии, что отношения, которые должны создавать 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)

В этом примере вывод ограничивается 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, потоковая передача) для дополнительных примеров потоковой передачи).

AS

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

схема

Схема с использованием ключевого слова AS, заключённая в скобки (см. Схемы).

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

Используйте оператор STREAM для отправки данных через внешнюю скрипт или программу. Несколько операторов stream могут появляться в одном скрипте Pig. Операторы 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;

О гарантиях данных

Гарантии данных определяются на основе позиции оператора потоковой передачи в скрипте 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] псевдоним, псевдоним [, псевдоним …];

Термины

псевдоним

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

ONSCHEMA

Используйте предложение ONSCHEMA для определения объединения по именованным полям (вместо позиционного обозначения). Все входные данные для объединения должны иметь не неопределенную (не нулевую) схему.

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

Используйте оператор 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

ОПРЕДЕЛИТЬ (UDFs, потоковая обработка)

Присваивает псевдоним UDF или команде потоковой обработки.

Синтаксис: UDF и потоковая обработка

ОПРЕДЕЛИТЬ псевдоним {функция | [`команда` [вход] [выход] [пересылка] [кэш] [ошибка] ] };

Термины

псевдоним

Имя функции UDF или имя команды потоковой обработки (cmd_alias для оператора STREAM).

функция

Для использования с функциями.

Имя функции UDF.

`команда`

Для использования с потоковой обработкой.

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

Описания пунктов (вход, выход, пересылка, кэш, ошибка) приведены ниже. Обратите внимание на следующее:

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

вход

Для использования с потоковой обработкой.

ВХОД ( {stdin | 'путь'} [Используя сериализатор] [, {stdin | 'путь'} [Используя сериализатор] …] )

Где:

  • ВХОД – Ключевое слово.

  • 'путь' – Путь к файлу, заключенный в одинарные кавычки.

  • Используя – Ключевое слово.

  • сериализатор – По умолчанию используется PigStreaming.

выход

Для использования с потоковой обработкой.

ВЫХОД ( {stdout | stderr | 'путь'} [Используя десериализатор] [, {stdout | stderr | 'путь'} [Используя десериализатор] …] )

Где:

  • ВЫХОД – Ключевое слово.

  • 'путь' – Путь к файлу, заключенный в одинарные кавычки.

  • Используя – Ключевое слово.

  • десериализатор – По умолчанию используется PigStreaming.

пересылка

Для использования с потоковой обработкой.

ПЕРЕСЫЛКА('путь' [, 'путь' …])

Где:

  • ПЕРЕСЫЛКА – Ключевое слово.

  • 'путь' – Путь к файлу, заключенный в одинарные кавычки.

кэш

Для использования с потоковой обработкой.

КЭШ('dfs_путь#dfs_файл' [, 'dfs_путь#dfs_файл' …])

Где:

  • КЭШ – Ключевое слово.

  • 'dfs_путь#dfs_файл' – Путь/имя файла на распределенной файловой системе, заключенные в одинарные кавычки. Пример: '/mydir/mydata.txt#mydata.txt'

ошибка

Для использования с потоковой обработкой.

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 <file>' ).

    /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-файл, чтобы можно было использовать UDF в нём.

Синтаксис

ЗАРЕГИСТРИРОВАТЬ путь;

Термины

путь

Путь к JAR-файлу (требуется полный URI расположения). Не заключайте имя в кавычки.

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

Скрипты Pig

Используйте оператор ЗАРЕГИСТРИРОВАТЬ внутри скрипта 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

© 2007–2016 Apache Software Foundation
Licensed under the Apache Software License version 2.0.
https://pig.apache.org/docs/r0.14.0/basic.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API