Spec-Zone.ru › Apache Pig 0.17

Основы Pig Latin

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

Правила

Здесь описаны соглашения по синтаксису и примерам кода в Справочнике по Pig Latin.

Соглашение

Описание

Пример

( )

Скобки заключают один или несколько элементов.

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

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

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

[ ]

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

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

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

[INNER | OUTER]

{ }

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

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

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

{ block | nested_block }

…

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

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

cat path [path …]

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

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

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

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

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

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

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

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

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

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

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

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

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

-- А

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

-- Б

bag, BinStorage, by, bytearray, BIGINTEGER, BIGDECIMAL

-- В

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

-- Г

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

-- Е

e, E, eval, exec, explain

-- Ж

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

-- З

generate, group

-- И

help

-- К

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

-- Л

join

-- М

kill

-- Н

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

-- О

map, matches, MAX, MIN, mkdir, mv

-- П

not, null

-- Р

onschema, or, order, outer, output

-- С

parallel, pig, PigDump, PigStorage, pwd

-- Т

quit

-- У

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

-- Ф

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

-- Х

TextLoader, TOKENIZE, through, tuple

-- Ц

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

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

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

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

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

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

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

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

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

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

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

Типы данных

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

Простые типы

Описание

Пример

int

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

10

long

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

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

Отображение: 10L

float

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

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

Отображение: 10.5F или 1050.0F

double

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

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

Отображение: 10.5 или 1050.0

chararray

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

hello world

bytearray

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

boolean

булево

true/false (регистр не учитывается)

datetime

дата и время

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 преобразуются в двойную точность, потому что мы не знаем тип ни f1, ни f2.

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

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

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

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

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

Кортеж

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

Синтаксис

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

Термины

( )

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

поле

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

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

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

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

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

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

Пример

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

(John,18,4.0F)

Мешок

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

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

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

Термины

{ }

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

tuple

Кортеж.

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

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

  • Мешок может содержать повторяющиеся кортежи.

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

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

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

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

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

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

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

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

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

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

Отображение

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

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

[ key#value <, key#value …> ]

Термины

[ ]

Отображения заключены в квадратные скобки [ ].

#

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

key

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

value

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

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

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

Также см. схемы отображений.

Пример

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

[name#John,phone#5551212]

Null и Pig Latin

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

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

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

Оператор

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

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

==, !=

>, <

>=, <=

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

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

matches

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

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

+ , -, *, /

% modulo

? : bincond

CASE : case

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

Оператор NULL:

is null

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

Оператор NULL:

is not null

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

Операторы дереференции:

tuple (.) или map (#)

Если дереференцируемое кортеж или карта имеют значение NULL, возвращается NULL.

Операторы:

COGROUP, GROUP, JOIN

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

Функция:

COUNT_STAR

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

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

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

Функции:

AVG, MIN, MAX, SUM, COUNT

Эти функции игнорируют NULL.

Функция:

CONCAT

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

Функция:

SIZE

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

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

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

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

Нули и константы

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

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

A = LOAD 'data' AS (a, b, c).
B = FOREACH A GENERATE a, 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;

Операции, возвращающие нули

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

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

  • Возвращаемые значения из пользовательских функций (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)

Нули и функции загрузки

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

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

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

A = LOAD 'student' AS (name, age, gpa); 
B = FILTER A BY name is not 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 перед соединением.)

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 or 1.92e2f

double

19.2 or 1.92e2

chararray

'hello world'

bytearray

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

boolean

true/false

Регистр не учитывается.

biginteger

19211921192119211921BI

bigdecimal

192119211921.192119211921BD

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

tuple

(19, 2, 1)

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

bag

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

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

map

[ '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)

    • BD или bd в этом случае ей присваивается тип BigDecimal (например, 12345678.12345678BD)

  • BigIntegers могут быть указаны, добавив BI или bi в конце числа (например, 123456789123456BI)

  • Нет встроенного типа константы для поля datetime. Вы можете использовать ToDate udf с константой 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 — оба массива символов:

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

Термины

псевдоним

Присвоенное имя полю.

тип

(Необязательно) Простой тип данных, присвоенный полю.

Псевдоним и тип разделяются двоеточием ( : ).

Если тип опущен, поле по умолчанию имеет тип 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)

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

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

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

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

Синтаксис

псевдоним[:кортеж] (псевдоним[:тип]) [, (псевдоним[:тип]) …] )

Термины

псевдоним

Присвоенное имя кортежу.

:кортеж

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

( )

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

псевдоним[:тип]

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

  • псевдоним – присвоенное имя полю

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

Примеры

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

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

Схемы множеств

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

Синтаксис

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

Термины

alias

Присвоенное имя мешку.

:bag

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

{ }

Обозначение мешка, набор фигурных скобок.

tuple

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

Примеры

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

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

Схемы карт

Карта представляет собой набор пар ключ-значение.

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

alias<:map> [ <type> ]

Термины

alias

Присвоенное имя карте.

:map

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

[ ]

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

type

(Необязательно) Тип данных (разрешены все типы, по умолчанию 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 должны совпадать.

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

выбор

CASE WHEN THEN ELSE END

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

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

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

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

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

Примеры

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

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

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

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

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

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

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

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

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

В этом примере оператор выбора используется с полем 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 преобразуется к этому типу данных

bag

кортеж

карта

int

long

float

double

chararray

bytearray

bag

ошибка

ошибка

ошибка

ошибка

ошибка

ошибка

ошибка

ошибка

ошибка

кортеж

еще нет

ошибка

ошибка

ошибка

ошибка

ошибка

ошибка

ошибка

карта

ошибка

ошибка

ошибка

ошибка

ошибка

ошибка

ошибка

int

int

long

float

double

ошибка

приведение к int

long

long

float

double

ошибка

приведение к long

float

float

double

ошибка

приведение к типу float

double

double

ошибка

приведение к типу double

chararray

ошибка

ошибка

bytearray

приведение к типу double

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

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

мешок

кортеж

карта

целое

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

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

двойное

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

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

мешок

ошибка

ошибка

ошибка

еще нет

еще нет

еще нет

еще нет

ошибка

ошибка

кортеж

ошибка

ошибка

еще нет

еще нет

еще нет

еще нет

ошибка

ошибка

карта

ошибка

ошибка

ошибка

ошибка

ошибка

ошибка

ошибка

целое

целое

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

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

двойное

ошибка

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

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

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

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

двойное

ошибка

преобразование в длинное целое

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 (true или false).

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

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

Описание

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

от / до

сумка

кортеж

карта

целое

длинное

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

двойное

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

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

логическое

сумка

ошибка

ошибка

ошибка

ошибка

ошибка

ошибка

ошибка

ошибка

ошибка

кортеж

ошибка

ошибка

ошибка

ошибка

ошибка

ошибка

ошибка

ошибка

ошибка

карта

ошибка

ошибка

ошибка

ошибка

ошибка

ошибка

ошибка

ошибка

ошибка

целое

ошибка

ошибка

ошибка

да

да

да

да

ошибка

ошибка

long

ошибка

ошибка

ошибка

да

да

да

да

ошибка

ошибка

float

ошибка

ошибка

ошибка

да

да

да

да

ошибка

ошибка

double

ошибка

ошибка

ошибка

да

да

да

да

ошибка

ошибка

chararray

ошибка

ошибка

ошибка

да

да

да

да

ошибка

да

bytearray

да

да

да

да

да

да

да

да

да

boolean

ошибка

ошибка

ошибка

ошибка

ошибка

ошибка

ошибка

да

ошибка

Синтаксис

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

Термины

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

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

поле

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

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

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

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

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

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

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

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

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

Примеры

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

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

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

B = GROUP A BY f1;

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

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

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

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

В этом примере bytearray (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))

В этом примере bytearray (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) приводится к типу map.

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 используется явное преобразование. Если сумме не присвоено имя, можно использовать позицию (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.*');

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

мешок

кортеж

карта

целое

длинное

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

двойное

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

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

булево

дата и время

большое целое

большая десятичная

мешок

ошибка

ошибка

ошибка

ошибка

ошибка

ошибка

ошибка

ошибка

ошибка

ошибка

ошибка

ошибка

ошибка

кортеж

булево

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

ошибка

ошибка

ошибка

ошибка

ошибка

ошибка

ошибка

ошибка

ошибка

ошибка

ошибка

карта

булево

(см. Примечание 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)

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

мешок

кортеж

карта

целое

длинное

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

двойное

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

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

логическое

дата/время

большое целое

большая десятичная

мешок

ошибка

ошибка

ошибка

ошибка

ошибка

ошибка

ошибка

ошибка

ошибка

ошибка

ошибка

ошибка

ошибка

кортеж

ошибка

ошибка

ошибка

ошибка

ошибка

ошибка

ошибка

ошибка

ошибка

ошибка

ошибка

ошибка

карта

ошибка

ошибка

ошибка

ошибка

ошибка

ошибка

ошибка

ошибка

ошибка

ошибка

ошибка

int

boolean

boolean

boolean

boolean

ошибка

boolean (bytearray приведено к int)

ошибка

ошибка

ошибка

ошибка

long

boolean

boolean

boolean

ошибка

boolean (bytearray приведено к long)

ошибка

ошибка

ошибка

ошибка

float

boolean

boolean

ошибка

boolean (bytearray приведено к float)

ошибка

ошибка

ошибка

ошибка

double

boolean

ошибка

boolean (bytearray приведено к double)

ошибка

ошибка

ошибка

ошибка

chararray

boolean

boolean (bytearray cast as chararray)

ошибка

ошибка

ошибка

ошибка

bytearray

boolean

ошибка

ошибка

ошибка

ошибка

boolean

boolean

ошибка

ошибка

ошибка

datetime

boolean

ошибка

ошибка

biginteger

boolean

ошибка

bigdecimal

boolean

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

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

chararray

bytearray*

chararray

boolean

boolean

bytearray

boolean

boolean

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

Описание

Оператор

Символ

Примечания

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

( )

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

конструктор множества

{ }

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

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

[ ]

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

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

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

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

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

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

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

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

Примеры

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

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

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

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

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

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

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

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

Построение словарей

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

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

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

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

Описание

Оператор

Символ

Примечания

разыменование кортежа

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

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

разыменование мешка

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

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

разыменование словаря

map#'key'

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

Примеры

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

Предположим, у нас есть отношение 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)

Пример с мешком (Bag)

Предположим, у нас есть отношение 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)})

Пример с кортежем/мешком (Tuple/Bag)

Предположим, у нас есть отношение 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)})

Пример со словарем (Map)

Предположим, у нас есть отношение 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)
()
()
()

Оператор размыкания (Disambiguate)

После операций 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 A::y, z; -- Cannot simply refer to y as it can refer to A::y or B::y

В случаях, когда схема хранится как часть StoreFunc, например PigStorage, JsonStorage, AvroStorage или OrcStorage, пользователи обычно должны использовать дополнительный оператор FOREACH перед STORE для переименования имён полей и удаления оператора размыкания из имён. Для автоматического удаления оператора размыкания из схемы для операции STORE можно установить свойство pig.store.schema.disambiguate в Pig в значение "false". Ответственность пользователя заключается в обеспечении отсутствия конфликтов в именах полей при использовании этого параметра.

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

Оператор 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 создаёт кортеж с двумя полями, содержащими ключ и значение. Если у нас есть поле словаря с именем kvpair со входом (m[k1#v1, k2#v2]) и мы применяем GENERATE flatten(kvpair), то будет сгенерировано два кортежа (k1,v1) и (k2,v2), к которым можно обратиться как kvpair::key и kvpair::value.
Если в выражении есть дополнительные проекции, то произойдёт декартово произведение, подобно мешкам. Например, если мы применим выражение GENERATE $0, FLATTEN($1) к входному кортежу (a, m[k1#1, k2#2, k3#3]), мы получим (a,k1,1), (a,k2,2) и (a,k3,3) в качестве результата.

Также обратите внимание, что 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;

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

bag

ошибка

tuple

ошибка

map

ошибка

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

  • Подробнее см. 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)

КУБ

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

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

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

Операция сводки

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

Синтаксис

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

Термины

alias

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

CUBE

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

BY

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

выражение

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

ROLLUP

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

PARALLEL n

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

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

Пример

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

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

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

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

Схема вывода

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

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

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

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

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

(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 используются вместе, выходные группы будут представлять собой декартово произведение всех групп, сгенерированных операциями cube и rollup. Если в операциях cube есть m измерений, а в операциях rollup — n измерений, общее количество комбинаций составит (2^m) * (n+1).

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

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

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

Схема вывода

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

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

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

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

ОПРЕДЕЛИТЬ

См.:

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

DISTINCT

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

Синтаксис

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

Термины

alias

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

PARTITION BY partitioner

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

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

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

PARALLEL n

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

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

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

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

Пример

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

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

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

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

X = DISTINCT A;

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

FILTER

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

Синтаксис

alias = FILTER alias BY 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;
……

Пример разворачивания для типа карты. Здесь мы загружаем целое число и карту (целочисленных значений) в A. Затем m разворачивается, и, наконец, мы фильтруем результат, чтобы включать только кортежи, где значение среди не вложенных записей карты было 5.

A = LOAD 'data' AS (a:int, m:map[int]);
B = FOREACH A GENERATE a, FLATTEN(m);
C = FILTER B by m::value == 5;
……

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

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

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

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

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

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

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

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

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

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

B = GROUP A BY url;

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

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

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

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

GROUP

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

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

Синтаксис

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

Термины

alias

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

Вы можете использовать COGROUP до 127 отношений за один раз.

ALL

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

B = GROUP A ALL;

BY

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

B = GROUP A BY f1;

expression

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

B = GROUP A BY (key1,key2);

USING

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

'collected'

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

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

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

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

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

'merge'

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

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

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

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

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

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

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

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

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

PARTITION BY partitioner

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

  • Для получения более подробной информации см. http://hadoop.apache.org/docs/current/api/org/apache/hadoop/mapred/Partitioner.html

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

PARALLEL n

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

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

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

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

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

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

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

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

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

  • Операторы GROUP/COGROUP и JOIN обрабатывают значения NULL по-разному (см. Значения NULL и операторы 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 по полю "age" для формирования отношения B. Мы можем использовать операторы DESCRIBE и ILLUSTRATE для изучения структуры отношения B. Отношение B имеет два поля. Первое поле называется "group" и имеет тип int, такой же, как поле "age" в отношении A. Второе поле называется "A" после отношения A и имеет тип bag.

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)

В этом примере кортежи группируются совместно, используя поле «владелец» из отношения A и поле «друг2» из отношения B в качестве ключевых полей. Оператор DESCRIBE показывает схему отношения X, которое имеет три поля: «группа», «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' | 'bloom' | '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'

Используется для выполнения реплицированных объединений (см. Реплицированные объединения).

'bloom'

Используется для выполнения объединений bloom (см. Объединения bloom).

'skewed'

Используется для выполнения наклоненных объединений (см. Наклоненные объединения).

'merge'

Используется для выполнения объединений merge (см. Объединения merge).

'merge-sparse'

Используется для выполнения объединений merge-sparse (см. Объединения 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 обрабатывают значения NULL по-разному (см. NULL и оператор 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' | 'bloom' | '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'

Используется для выполнения реплицированных соединений (см. Реплицированные соединения).

Для реплицированных соединений поддерживается только левое внешнее соединение.

'bloom'

Используется для выполнения bloom-соединений (см. Bloom-соединения).

Для bloom-соединений не поддерживается полное внешнее соединение.

'skewed'

Используется для выполнения смещённых соединений (см. Смещённые соединения).

'merge'

Используется для выполнения объединяющих соединений (см. Объединяющие соединения).

PARTITION BY partitioner

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

  • Для получения более подробной информации см. http://hadoop.apache.org/docs/current/api/org/apache/hadoop/mapred/Partitioner.html

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

Эта функция НЕ может использоваться со смещёнными соединениями.

PARALLEL n

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

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

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

Используйте оператор JOIN с соответствующими ключевыми словами для выполнения левых, правых или полных внешних объединений. Ключевое слово OUTER является необязательным для внешних объединений; ключевые слова LEFT, RIGHT и FULL подразумевают левое внешнее, правое внешнее и полное внешнее объединение соответственно, если OUTER опущено. Синтаксис Pig Latin тесно придерживается стандарта SQL.

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

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

  • Внешние объединения будут работать только для двусторонних объединений; для выполнения многостороннего внешнего объединения вам необходимо выполнить несколько двусторонних операторов внешнего объединения.

Примеры

Этот пример демонстрирует левое внешнее объединение.

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

Этот пример демонстрирует bloom правое внешнее объединение.

A = LOAD 'large';
B = LOAD 'small';
C= JOIN A BY $0 RIGHT, B BY $0 USING 'bloom';

Этот пример демонстрирует асимметричное полное внешнее объединение.

A = LOAD 'studenttab' as (name, age, gpa);
B = LOAD 'votertab' as (name, age, registration, contribution);
C = JOIN A BY name FULL, B BY name USING 'skewed';

LIMIT

Ограничивает количество выходных кортежей.

Синтаксис

alias = LIMIT alias n;

Термины

alias

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

n

Количество выходных кортежей, либо:

  • константа (например, 3)
  • скаляр, используемый в выражении (например, c.sum/100)

Примечание: Выражение может состоять из констант или скаляров; оно не может содержать столбцы из входного отношения.

Примечание: Использование скаляра вместо константы в LIMIT автоматически отключает большинство оптимизаций (выполняется только push-before-foreach).

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

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

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

Если указанное количество выходных кортежей меньше количества кортежей в отношении, возвращаются n кортежей. Нет гарантии, какие именно n кортежей будут возвращены, и возвращаемые кортежи могут меняться от одной обработки к другой. Конкретный набор кортежей можно запросить, используя оператор ORDER, за которым следует LIMIT.

Примечание: Оператор LIMIT позволяет Pig избежать обработки всех кортежей в отношении. В большинстве случаев запрос, использующий LIMIT, будет выполняться более эффективно, чем идентичный запрос, не использующий LIMIT. Всегда рекомендуется использовать limit, если это возможно.

Примеры

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

a = load 'a.txt';
b = group a all;
c = foreach b generate COUNT(a) as sum;
d = order a by $0;
e = limit d c.sum/100;

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

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

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

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

X = LIMIT A 3;

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

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

B = ORDER A BY f1 DESC, f2 ASC;

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

X = LIMIT B 3;

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

ЗАГРУЗКА

Загружает данные из файловой системы.

Синтаксис

ЗАГРУЗКА 'данные' [Используя функцию] [Как схема];

Термины

'данные'

Имя файла или каталога в одинарных кавычках.

Если вы указываете имя каталога, загружаются все файлы в этом каталоге.

Вы можете использовать Hadoop-глобинг для указания файлов на уровне файловой системы или каталога (см. Hadoop globStatus для получения подробностей о синтаксисе глобинга).

Примечание: Pig использует Hadoop-глобинг, поэтому функциональность ИДЕНТИЧНА. Однако при запуске из командной строки с помощью команды Hadoop fs (а не оператора Pig LOAD), оболочка Unix может выполнить некоторые подстановки; это может изменить результат, создав впечатление, что глобинг работает по-разному для 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.

функция

Функция загрузки.

  • Вы можете использовать встроенную функцию (см. Функции загрузки/хранения). PigStorage является функцией загрузки по умолчанию и не нуждается в указании (просто опустите предложение USING).

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

AS

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

схема

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

NATIVE

Выполняет задачи MapReduce/Tez внутри скрипта Pig.

Синтаксис

alias1 = NATIVE 'native.jar' STORE alias2 INTO 'inputLocation' USING storeFunc LOAD 'outputLocation' USING loadFunc AS schema [`params, ... `];

Термины

alias1, alias2

Имена отношений.

native.jar

Файл jar, содержащий программу MapReduce или Tez (в одинарных кавычках).

Вы можете указать любой файл jar MapReduce/Tez, который можно запустить через команду hadoop jar native.jar params.

Значения для inputLocation и outputLocation можно передать в params.

STORE ... INTO ... USING

См. STORE

Сохранить alias2 в inputLocation с помощью storeFunc, который затем используется задачей MapReduce/Tez для чтения данных.

LOAD ... USING ... AS

См. LOAD

После выполнения задачи MapReduce/Tez native.jar загрузить данные из outputLocation в alias1 с помощью loadFunc как схемы.

`params, ...`

Дополнительные параметры, необходимые для работы задачи MapReduce/Tez (в обратных кавычках).

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

Используйте оператор NATIVE для запуска задач MapReduce/Tez изнутри скрипта Pig.

Места расположения входных и выходных данных программы MapReduce/Tez передаются Pig с помощью операторов STORE/LOAD. Однако Pig не передает эту информацию (и не требует передачи) программе MapReduce/Tez. Если вы хотите передать места расположения входных и выходных данных программе MapReduce/Tez, вы можете использовать оператор params или напрямую задать места расположения в программе MapReduce/Tez.

Пример

Этот пример демонстрирует, как запустить программу MapReduce wordcount из Pig. Обратите внимание, что файлы, указанные как места расположения входных и выходных данных в операторе NATIVE, НЕ будут автоматически удалены Pig. Вам нужно будет удалить их вручную.

A = LOAD 'WordcountInput.txt';
B = NATIVE 'wordcount.jar' STORE A INTO 'inputDir' LOAD 'outputDir'
    AS (word:chararray, count: int) `org.myorg.WordCount inputDir outputDir`;

Сортировка

Сортирует отношение на основе одного или нескольких полей.

Синтаксис

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)
            

ВЫБОРКА

Выбирает случайную выборку данных на основе указанного размера выборки.

Синтаксис

ВЫБОРКА псевдоним размер;

Термины

псевдоним

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

размер

Размер выборки, либо

  • константа, диапазон от 0 до 1 (например, введите 0,1 для 10%)
  • скаляр, используемый в выражении

Примечание: выражение может состоять из констант или скаляров; оно не может содержать столбцы из входного отношения.

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

Используйте оператор ВЫБОРКА для выбора случайной выборки данных с указанным размером выборки. Оператор ВЫБОРКА является вероятностным; нет гарантии, что каждое использование оператора вернёт ровно одинаковое количество кортежей для данного размера выборки.

Пример

В этом примере отношение 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_STAR(a) AS num_rows;
d = SAMPLE a (double)1000/c.num_rows;

РАЗДЕЛЕНИЕ

Разделяет отношение на два или более отношений.

Синтаксис

РАЗДЕЛЕНИЕ псевдоним В псевдоним ЕСЛИ выражение, псевдоним ЕСЛИ выражение [, псевдоним ЕСЛИ выражение …] [, псевдоним ИНАЧЕ];

Термины

псевдоним

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

В

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

ЕСЛИ

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

выражение

Выражение.

ИНАЧЕ

Необязательное ключевое слово. Обозначает отношение по умолчанию.

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

Используйте оператор РАЗДЕЛЕНИЕ для разделения содержимого отношения на два или более отношений на основе некоторого выражения. В зависимости от условий, указанных в выражении:

  • Кортеж может быть назначен более чем одному отношению.

  • Кортеж может не быть назначен ни одному отношению.

Пример

В этом примере отношение 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 завершится ошибкой.

Выходные файлы данных, имеющие имена part-nnnnn, записываются в этот каталог.

Используя

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

Если операнд 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

ПОТОК

Отправляет данные во внешний скрипт или программу.

Синтаксис

alias = STREAM alias [, alias …] THROUGH {`command` | cmd_alias } [AS schema] ;

Термины

alias

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

THROUGH

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

`command`

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

cmd_alias

Имя команды, созданной с помощью оператора DEFINE (см. DEFINE (UDFs, streaming) для дополнительных примеров стримминга).

AS

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

schema

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

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

Используйте оператор STREAM для отправки данных через внешний скрипт или программу. Несколько операторов stream могут появиться в одном скрипте Pig. Операторы stream могут быть расположены рядом друг с другом или с другими операциями между ними.

При использовании с командой оператор stream может выглядеть так:

A = LOAD 'data';

B = STREAM A THROUGH `stream.pl -n 5`;

При использовании с cmd_alias оператор stream может выглядеть так, где mycmd - определённое имя.

A = LOAD 'data';

DEFINE mycmd `stream.pl –n 5`;

B = STREAM A THROUGH mycmd;

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

Гарантии данных определяются на основе позиции оператора stream в скрипте Pig.

  • Неупорядоченные данные – Нет гарантий порядка, в котором данные будут переданы приложению для обработки потоков.

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

  • Сгруппированные и упорядоченные данные – Данные с одинаковым ключом группировки гарантированно будут переданы приложению для обработки потоков непрерывно. Кроме того, данные в группе гарантированно будут отсортированы по предоставленному вторичному ключу.

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

Пример: Гарантии данных

В этом примере данные неупорядочены.

A = LOAD 'data';

B = STREAM A THROUGH `stream.pl`;

В этом примере данные сгруппированы.

A = LOAD 'data';

B = GROUP A BY $1;

C = FOREACH B FLATTEN(A);

D = STREAM C THROUGH `stream.pl`;

В этом примере данные сгруппированы и упорядочены.

A = LOAD 'data';

B = GROUP A BY $1;

C = FOREACH B {
      D = ORDER A BY ($3, $4);
      GENERATE D;
}

E = STREAM C THROUGH `stream.pl`;

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

В этом примере схема задаётся как часть оператора STREAM.

X = STREAM A THROUGH `stream.pl` as (f1:int, f2:int, f3:int);

ОБЪЕДИНЕНИЕ

Вычисляет объединение двух или более отношений.

Синтаксис

alias = UNION [ONSCHEMA] alias, alias [, alias …] [PARALLEL n];

Термины

alias

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

ONSCHEMA

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

PARALLEL n

Это применимо только для режима выполнения Tez и не будет работать с режимом Mapreduce. Указание PARALLEL добавит дополнительный шаг reduce, что немного снизит производительность. Основная цель в этом случае — управление количеством выходных файлов.

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

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

Используйте оператор UNION для объединения содержимого двух или более отношений. Оператор UNION:

  • Не сохраняет порядок кортежей. Как входные, так и выходные отношения интерпретируются как неупорядоченные множества кортежей.

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

  • Не исключает дублирующиеся кортежи.

Поведение схемы

Поведение схем для UNION (позиционная запись / типы данных) и UNION ONSCHEMA (именованные поля / типы данных) одинаковое, за исключением случаев, где указано иначе.

Объединение отношений с разными размерами приводит к схеме null (только объединение):

A: (a1:long, a2:long) 
B: (b1:long, b2:long, b3:long) 
A union B: null 

Объединение столбцов с несовместимыми типами приводит к ошибке. (См. Таблицу типов для сложения и вычитания для несовместимых типов.)

A: (a1:long)
B: (a1:chararray)
A union B: ERROR: Cannot cast from long to bytearray

Объединение столбцов совместимого типа даст тип «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

DEFINE (UDFs, потоковая обработка)

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

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

DEFINE alias {function | [`command` [input] [output] [ship] [cache] [stderr] ] };

Термины

alias

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

function

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

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

`command`

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

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

Описания разделов (input, output, ship, cache, stderr) приведены ниже. Обратите внимание на следующее:

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

input

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

INPUT ( {stdin | 'путь'} [USING сериализатор] [, {stdin | 'путь'} [USING сериализатор] …] )

Где:

  • INPUT – Ключевое слово.

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

  • USING – Ключевое слово.

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

output

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

OUTPUT ( {stdout | stderr | 'путь'} [USING десериализатор] [, {stdout | stderr | 'путь'} [USING десериализатор] …] )

Где:

  • OUTPUT – Ключевое слово.

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

  • USING – Ключевое слово.

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

ship

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

SHIP('путь' [, 'путь' …])

Где:

  • SHIP – Ключевое слово.

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

cache

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

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

Где:

  • CACHE – Ключевое слово.

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

stderr

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

STDERR( '/dir') или STDERR( '/dir' LIMIT n)

Где:

  • '/dir' — это каталог журнала, заключённый в одинарные кавычки.
  • (необязательно) LIMIT n — это порог ошибок, где n — целое значение. Если не указано, пороговое значение ошибок не ограничено.

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

Используйте оператор DEFINE для присвоения имени (псевдонима) функции UDF или команде потоковой передачи.

Используйте DEFINE для указания функции UDF, когда:

  • Функция имеет длинное имя пакета, которое вы не хотите включать в скрипт, особенно если вы вызываете функцию несколько раз в этом скрипте.

  • Конструктор функции принимает строковые параметры. Если вам нужно использовать разные параметры конструктора для разных вызовов функции, вам необходимо создать несколько определений — по одному для каждого набора параметров.

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

  • Спецификация команды потоковой передачи сложная.

  • Спецификация команды потоковой передачи требует дополнительных параметров (ввода, вывода и т. д.).

О вводе и выводе для потоковой передачи

Для преобразования данных из кортежей в формат, который может обрабатываться приложением потоковой передачи, необходима сериализация. Для преобразования вывода приложения потоковой передачи обратно в кортежи необходима десериализация. 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 both the front end and 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;
}
О команде Ship

Используйте опцию ship для отправки бинарных данных потоковой передачи и, при необходимости, поддерживающих файлов с узла клиента на вычислительные узлы. Pig не отправляет зависимости автоматически; вы несете ответственность за явное указание всех зависимостей и за то, чтобы программное обеспечение, от которого зависит обработка (например, perl или python), было установлено в кластере. Поддерживающие файлы отправляются в текущую рабочую директорию задачи, и должны указываться только относительные пути. Любые предварительно установленные двоичные файлы должны указываться в переменной PATH.

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

Обратите внимание, что параметр ship имеет два компонента: указание источника, заданное в предложении ship( ), — это представление вашей машины; указание команды — это представление фактического кластера. Единственная гарантия состоит в том, что отправленные файлы будут доступны в текущей рабочей директории запущенной задачи, и что ваша текущая рабочая директория также находится в переменной окружения PATH.

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

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

  • Безопасно отправлять только файлы для выполнения из текущей рабочей директории задачи на кластере.

    OP = stream IP through 'script';
    or
    DEFINE CMD 'script' ship('/a/b/script');
    OP = stream IP through CMD;
    
  • Отправка файлов по относительным или абсолютным путям не определена и в основном завершится ошибкой, поскольку у вас может не быть разрешений на чтение/запись/выполнение из произвольных путей на фактических кластерах.

О кэше

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

Об автоматической отправке

Если параметры ship и cache не указаны, Pig попытается автоматически отправить бинарный файл следующим образом:

  • Если первое слово в команде потоковой передачи — perl или python, Pig предполагает, что бинарный файл — это первая нецитируемая строка, которая не начинается с тире.

  • В противном случае Pig попытается отправить первую строку из командной строки, если она не взята из /bin, /usr/bin, /usr/local/bin. Pig определит это, просканировав путь, если указан абсолютный путь, или выполнив which. Пути можно сделать настраиваемыми, используя параметр set stream.skippath (можно использовать несколько команд set для указания более одного пути для пропуска).

Если вы не предоставили DEFINE для данной команды потоковой передачи, автоматическая отправка отключена.

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

  • Если 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;

Примеры: Передача/Кэширование

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

DEFINE Y 'stream.pl' SHIP('/work/stream.pl');

X = STREAM A THROUGH Y;

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

DEFINE Y 'stream.pl data.gz' SHIP('/work/stream.pl') CACHE('/input/data.gz#data.gz');

X = STREAM A THROUGH Y;

Пример: DEFINE с 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);

REGISTER (jar/скрипт)

Регистрирует JAR-файл, чтобы можно было использовать UDF из этого файла.

Синтаксис

REGISTER path;

Термины

path

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

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

Скрипты Pig

Используйте оператор REGISTER в скрипте Pig для указания файла JAR или модуля Python/JavaScript. Pig поддерживает файлы JAR и модули, хранящиеся в локальных файловых системах, а также в распределенных удаленных файловых системах, таких как HDFS и Amazon S3 (см. Pig Scripts).

Кроме того, файлы JAR, хранящиеся в локальных файловых системах, могут быть указаны как шаблон glob с использованием «*». Pig будет искать совпадающие JAR-файлы в локальной файловой системе, либо по относительному пути (относительно вашей рабочей директории), либо по абсолютному пути. Pig загрузит все JAR-файлы, соответствующие шаблону glob.

Командная строка

Вы можете зарегистрировать дополнительные файлы (для использования со своим скриптом 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

REGISTER (артефакт)

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

Синтаксис

Чтобы загрузить артефакт (и его зависимости), вам необходимо указать группу, модуль и версию артефакта, следуя приведенному ниже синтаксису. Эта команда загрузит указанный JAR-файл и все его зависимости и загрузит его в класспаth.

REGISTER ivy://group:module:version?querystring

Термины

Группа

Группа модуля, из которой происходит модуль. Соответствует Maven groupId или Ivy Organization.

Модуль

Имя загружаемого модуля. Соответствует Maven artifactId или Ivy artifact.

Версия

Используемая версия модуля. Можно указать конкретную версию или использовать "+" или "*" для использования последней версии.

Строка запроса

Содержит пары ключ-значение, разделённые "&", чтобы помочь нам исключить все или определённые зависимости и т.д.

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

Команда Register artifact является расширением команды register, используемой для регистрации jar-файла. Помимо регистрации jar-файла из локальной системы или из hdfs, теперь можно указать координаты артефакта, и Pig загрузит артефакт (и его зависимости, если необходимо) из настроенного репозитория.

Поддерживаемые параметры в строке запроса
  • Транзитивные зависимости

    Transitive позволяет указать, нужны ли зависимости вместе с регистрируемым jar-файлом. Установив transitive в false в строке запроса, можно указать Pig регистрировать только артефакт без зависимостей. Это загрузит только указанный артефакт и не загрузит зависимости jar-файла. По умолчанию значение transitive равно true.

    Синтаксис

    REGISTER ivy://org:module:version?transitive=false

  • Исключение зависимостей

    При регистрации артефакта, если вы хотите исключить некоторые зависимости, можно указать их с помощью ключа exclude. Предположим, вам нужна определённая версия зависимого jar-файла, которая не соответствует версии jar-файла, автоматически полученного, тогда можно исключить такие зависимости, указав список зависимостей через запятую и зарегистрировать зависимый jar-файл отдельно.

    Синтаксис

    REGISTER ivy://org:module:version?exclude=org:mod,org:mod,...

  • Классификатор

    Некоторые зависимости Maven требуют классификаторов для разрешения. Можно указать их с помощью ключа classifier.

    Синтаксис

    REGISTER ivy://org:module:version?classifier=value

Другие свойства
  • Дополнительное свойство pig, pig.artifacts.download.location, может быть использовано для настройки расположения, куда должны быть загружены артефакты. По умолчанию они будут загружены в ~/.groovy/grapes

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

  • Поля Группа/Организация и Версия являются необязательными. В таких случаях вы можете оставить их пустыми.

  • Репозитории могут быть настроены с помощью файла ivysettings. Pig будет искать файл ivysettings.xml в следующих местах в порядке. PIG_CONF_DIR > PIG_HOME > Путь к классам

Примеры

  • Регистрация артефакта и всех его зависимостей.

                    -- Both are the same
    REGISTER ivy://org.apache.avro:avro:1.5.1
    REGISTER ivy://org.apache.avro:avro:1.5.1?transitive=true
  • Регистрация артефакта без получения его зависимостей.

                   REGISTER ivy://org.apache.avro:avro:1.5.1?transitive=false
  • Регистрация последнего артефакта.

                    -- Both of the following syntaxes work.
    REGISTER ivy://org.apache.avro:avro:+
    REGISTER ivy://org.apache.avro:avro:*
  • Регистрация артефакта с исключением определенных зависимостей.

                    REGISTER ivy://org.apache.pig:pig:0.10.0?exclude=commons-cli:commons-cli,commons-codec:commons-codec
  • Указание классификатора

                    REGISTER ivy://net.sf.json-lib:json-lib:2.4?classifier=jdk15
  • Регистрация артефакта без группы или организации. Просто пропустите их.

                    REGISTER ivy://:module:

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

Spec-Zone.ru

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