Spec-Zone.ru › Apache Pig 0.13

Основы Pig Latin

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

Конвенции

Здесь описаны конвенции для синтаксиса и примеров кода в Справочном руководстве по 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 Latin.

-- A

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

-- B

bag, BinStorage, by, bytearray, BIGINTEGER, BIGDECIMAL

-- C

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

-- D

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

-- E

e, E, eval, exec, explain

-- F

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

-- G

generate, group

-- H

help

-- I

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

-- J

join

-- K

kill

-- L

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

-- M

map, matches, MAX, MIN, mkdir, mv

-- N

not, null

-- O

onschema, or, order, outer, output

-- P

parallel, pig, PigDump, PigStorage, pwd

-- Q

quit

-- R

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

-- S

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

-- T

TextLoader, TOKENIZE, through, tuple

-- U

union, using

-- V, W, X, Y, Z

void

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

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

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

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

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

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

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

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

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

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

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

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

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

A
A123
abc_123_BeX_

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

_A123
abc_$
A!B

Отношения, мешки, кортежи, поля

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

  • Отношение — это мешок (точнее, внешний мешок).

  • Мешок — это набор кортежей.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Первое поле

Второе поле

Третье поле

Тип данных

chararray

int

float

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

$0

$1

$2

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

name

age

gpa

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

John

18

4.0

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Типы данных

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

Простые типы

Описание

Пример

int

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

10

long

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

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

Вывод: 10L

float

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

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

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

double

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

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

Вывод: 10.5 или 1050.0

chararray

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

hello world

bytearray

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

boolean

boolean

true/false (регистр не имеет значения)

datetime

datetime

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

biginteger

Java BigInteger

200000000000

bigdecimal

Java BigDecimal

33.456783321323441233442

Сложные типы

tuple

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

(19,2)

bag

Набор кортежей.

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

map

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

[open#apache]

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

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

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

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

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

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

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

Кортеж

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

Синтаксис

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

Термины

( )

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

поле

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

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

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

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

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

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

Пример

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

(John,18,4.0F)

Мешок

Мешок — это набор кортежей.

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

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

Термины

{ }

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

кортеж

Кортеж.

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

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

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

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

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

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

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

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

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

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

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

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

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

Карта

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

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

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

Термины

[ ]

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

#

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

ключ

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

значение

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

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

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

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

Пример

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

[name#John,phone#5551212]

Null-значения и Pig Latin

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

Null-значения, операторы и функции

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

Оператор

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

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

==, !=

>, <

>=, <=

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

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

matches

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

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

+ , -, *, /

% модуль

? : bincond

CASE : case

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

Оператор null:

is null

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

Оператор null:

is not null

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

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

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

Если разыменовываемый кортеж или карта имеют null-значение, возвращается null.

Операторы:

COGROUP, GROUP, JOIN

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

Функция:

COUNT_STAR

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

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

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

Функции:

AVG, MIN, MAX, SUM, COUNT

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

Функция:

CONCAT

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

Функция:

SIZE

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

Для булевых подвыражений обратите внимание на результаты при использовании null-значений с этими операторами:

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

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

Null-значения и константы

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

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

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

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

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

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

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

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

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

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

Операции, возвращающие Null-значения

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

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

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

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

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

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

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

В этом примере null-значения вводятся, если данные для полей отсутствуют.

cat data;
    2   3
4   
7   8   9

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

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

B = FOREACH A GENERATE f1,f2;

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

Null-значения и функции загрузки

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

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

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

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

Null-значения и операторы GROUP/COGROUP

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

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

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

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

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

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

Null-значения и оператор JOIN

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

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

Константы

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

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

Примечания

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

int

19

long

19L

float

19.2F или 1.92e2f

double

19.2 или 1.92e2

chararray

'hello world'

bytearray

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

boolean

true/false

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

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

кортеж

(19, 2, 1)

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

пакет

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

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

карта

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Схемы

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

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

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

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

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

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

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

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

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

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

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

Термины

alias

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

type

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

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

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

( , )

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

Примеры

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Синтаксис

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

Термины

alias

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

:tuple

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

( )

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

alias[:type]

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

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

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

Примеры

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

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

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

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

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

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

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

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

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

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

Схемы мешков

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

Синтаксис

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

Термины

псевдоним

Наименование, назначенное мешку.

:мешок

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

{ }

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

кортеж

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

Примеры

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

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

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

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

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

Схемы словарей

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

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

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

Термины

псевдоним

Наименование, назначенное словарю.

:словарь

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

[ ]

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

тип

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

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

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

Примеры

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

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

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

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

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

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

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

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

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

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

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

Пример

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

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

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

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

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

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

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

Описание

Оператор

Символ

Примечания

сложение

+

вычитание

-

умножение

*

деление

/

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

%

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

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

bincond

? :

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

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

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

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

case

CASE WHEN THEN ELSE END

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

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

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

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

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

Примеры

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

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

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

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

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

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

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

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

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

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

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

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

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

мешок

кортеж

словарь

int

long

float

double

chararray

bytearray

мешок

ошибка

ошибка

ошибка

ошибка

ошибка

ошибка

ошибка

ошибка

ошибка

кортеж

еще нет

ошибка

ошибка

ошибка

ошибка

ошибка

ошибка

ошибка

словарь

ошибка

ошибка

ошибка

ошибка

ошибка

ошибка

ошибка

int

int

long

float

double

ошибка

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

long

long

float

double

ошибка

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

float

float

double

ошибка

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

double

double

ошибка

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

chararray

ошибка

ошибка

bytearray

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

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

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

мешок

кортеж

карта

целое

длинное

с плавающей точкой

двойная точность

символьная строка

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

мешок

ошибка

ошибка

ошибка

ещё нет

ещё нет

ещё нет

ещё нет

ошибка

ошибка

кортеж

ошибка

ошибка

ещё нет

ещё нет

ещё нет

ещё нет

ошибка

ошибка

карта

ошибка

ошибка

ошибка

ошибка

ошибка

ошибка

ошибка

целое

целое

длинное

с плавающей точкой

двойная точность

ошибка

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

длинное

длинное

с плавающей точкой

двойная точность

ошибка

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

с плавающей точкой

с плавающей точкой

двойная точность

ошибка

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

двойная точность

двойная точность

ошибка

преобразование в двойную точность

символьная строка

ошибка

ошибка

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

преобразование в двойную точность

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

целое

длинное

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

целое

целое

длинное

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

длинное

длинное

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

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

ошибка

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

Описание

Оператор

Символ

Примечания

И

and

ИЛИ

or

В

in

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

НЕ

not

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

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

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

Описание

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

от / до

bag

tuple

map

int

long

float

double

chararray

bytearray

boolean

bag

ошибка

ошибка

ошибка

ошибка

ошибка

ошибка

ошибка

ошибка

ошибка

tuple

ошибка

ошибка

ошибка

ошибка

ошибка

ошибка

ошибка

ошибка

ошибка

map

ошибка

ошибка

ошибка

ошибка

ошибка

ошибка

ошибка

ошибка

ошибка

int

ошибка

ошибка

ошибка

да

да

да

да

ошибка

ошибка

long

ошибка

ошибка

ошибка

да

да

да

да

ошибка

ошибка

float

ошибка

ошибка

ошибка

да

да

да

да

ошибка

ошибка

double

ошибка

ошибка

ошибка

да

да

да

да

ошибка

ошибка

chararray

ошибка

ошибка

ошибка

да

да

да

да

ошибка

да

bytearray

да

да

да

да

да

да

да

да

да

boolean

ошибка

ошибка

ошибка

ошибка

ошибка

ошибка

ошибка

да

ошибка

Синтаксис

{(data_type) | (tuple(data_type)) | (bag{tuple(data_type)}) | (map[]) } field

Термины

(data_type)

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

field

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

Поле можно представить с помощью позиционной нотации или по имени (псевдоним). Например, если 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 может привести к потере битов.

Примеры

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

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) приводится к типу bag.

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

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

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

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

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

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

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

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

Описание

Оператор

Символ

Примечания

равно

==

не равно

!=

меньше

<

больше

>

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

<=

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

>=

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

matches

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

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

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

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

Примеры

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

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

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

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

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

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

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

мешок

кортеж

карта

int

long

float

double

chararray

bytearray

boolean

datetime

biginteger

bigdecimal

мешок

ошибка

ошибка

ошибка

ошибка

ошибка

ошибка

ошибка

ошибка

ошибка

ошибка

ошибка

ошибка

ошибка

кортеж

boolean

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

ошибка

ошибка

ошибка

ошибка

ошибка

ошибка

ошибка

ошибка

ошибка

ошибка

ошибка

карта

boolean

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

ошибка

ошибка

ошибка

ошибка

ошибка

ошибка

ошибка

ошибка

ошибка

ошибка

int

boolean

boolean

boolean

boolean

ошибка

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

ошибка

ошибка

ошибка

ошибка

long

boolean

boolean

boolean

ошибка

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

ошибка

ошибка

ошибка

ошибка

float

boolean

boolean

ошибка

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

ошибка

ошибка

ошибка

ошибка

double

boolean

ошибка

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

ошибка

ошибка

ошибка

ошибка

chararray

boolean

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

ошибка

ошибка

ошибка

ошибка

bytearray

boolean

ошибка

ошибка

ошибка

ошибка

boolean

boolean

ошибка

ошибка

ошибка

datetime

boolean

ошибка

ошибка

biginteger

boolean

ошибка

bigdecimal

boolean

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

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

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

bag

tuple

map

int

long

float

double

chararray

bytearray

boolean

datetime

biginteger

bigdecimal

bag

error

error

error

error

error

error

error

error

error

error

error

error

error

tuple

error

error

error

error

error

error

error

error

error

error

error

error

map

error

error

error

error

error

error

error

error

error

error

error

int

boolean

boolean

boolean

boolean

error

boolean (bytearray cast as int)

error

error

error

error

long

boolean

boolean

boolean

error

boolean (bytearray cast as long)

error

error

error

error

float

boolean

boolean

error

boolean (bytearray cast as float)

error

error

error

error

double

boolean

error

boolean (bytearray cast as double)

error

error

error

error

chararray

boolean

boolean (bytearray cast as chararray)

error

error

error

error

bytearray

boolean

error

error

error

error

boolean

boolean

error

error

error

datetime

boolean

error

error

biginteger

boolean

error

bigdecimal

boolean

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

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

chararray

bytearray*

chararray

boolean

boolean

bytearray

boolean

boolean

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

Описание

Оператор

Символ

Примечания

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

( )

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

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

{ }

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

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

[ ]

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

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

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

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

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

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

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

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

Примеры

Создание кортежа

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

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

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

Создание множества

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

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

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

Создание карты

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

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

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

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

Описание

Оператор

Символ

Замечания

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

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

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

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

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

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

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

map#'key'

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

Примеры

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

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

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

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

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

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

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

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

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

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

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

B = GROUP A BY f1;

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

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

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

X = FOREACH B GENERATE a.f1;

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

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

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

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

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

B = GROUP A BY (f1,f2);

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

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

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

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

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

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

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

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

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

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

X = FOREACH A GENERATE f2#'open';

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

Оператор разбиения неоднозначностей

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

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

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

Оператор FLATTEN

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

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

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

Также обратите внимание, что flatten пустого мешка приведет к тому, что строка будет отброшена; вывод не генерируется. (См. также Отбрасывание NULL перед объединением.)

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

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

Операторы NULL

Описание

Оператор

Символ

Замечания

is null

is null

is not null

is not null

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

Примеры

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

X = FILTER A BY f1 is not null;

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

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

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

Описание

Оператор

Символ

Замечания

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

+

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

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

-

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

Примеры

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

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

B = FOREACH A GENERATE -x, y;

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

мешок

ошибка

кортеж

ошибка

отображение

ошибка

int

int

long

long

float

float

double

double

chararray

ошибка

bytearray

double (как double)

datetime

ошибка

biginteger

biginteger

bigdecimal

bigdecimal

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

ASSERT

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

Синтаксис

ASSERT alias BY expression [, message];

Термины

alias

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

BY

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

expression

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

message

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

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

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

Примеры

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

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

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

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

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

COGROUP

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

CROSS

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

Синтаксис

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

Термины

alias

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

PARTITION BY partitioner

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

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

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

PARALLEL n

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

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

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

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

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

Пример

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

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

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

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

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

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

X = CROSS A, B;

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

CUBE

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

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

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

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

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

Синтаксис

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

Термины

alias

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

CUBE

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

BY

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

expression

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

ROLLUP

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

PARALLEL n

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

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

Пример

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

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

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

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

Схема вывода

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

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

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

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

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

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

Схема вывода

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

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

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

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

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

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

Схема вывода

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

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

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

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

DEFINE

См.:

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

DISTINCT

Удаляет дубликаты кортежей в отношении.

Синтаксис

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

Термины

alias

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

PARTITION BY partitioner

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

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

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

PARALLEL n

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

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

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

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

Пример

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

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

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

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

X = DISTINCT A;

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

FILTER

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

Синтаксис

alias = FILTER alias BY expression;

Термины

alias

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

BY

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

expression

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

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

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

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

Примеры

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

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

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

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

X = FILTER A BY f3 == 3;

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

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

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

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

FOREACH

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

Синтаксис

alias = FOREACH { block | nested_block };

Термины

alias

Имя отношения (внешний мешок).

block

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

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

См. Схемы

nested_block

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

alias = FOREACH nested_alias {

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

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

};

Где:

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

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

См. Схемы

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

expression

Выражение.

nested_alias

Имя внутреннего мешка.

nested_op

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

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

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

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

nested_exp

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

AS

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

schema

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

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

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

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

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

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

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

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

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

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

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

X = FOREACH A GENERATE *;

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

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

X = FOREACH A GENERATE a1, a2;

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

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

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

X = FOREACH C GENERATE group, B.b2;

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

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

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

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

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

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

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

DESCRIBE X;
x: {f1: int}

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

Y = FILTER X BY f1 > 10;

DUMP Y;
(11)
(12)

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

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

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

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

Пример: Уплощение

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

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

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

Ещё один пример использования FLATTEN.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

B = GROUP A BY url;

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

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

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

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

GROUP

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

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

Синтаксис

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

Термины

alias

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

Вы можете COGROUP до 127 отношений одновременно.

ALL

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

B = GROUP A ALL;

BY

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

B = GROUP A BY f1;

expression

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

B = GROUP A BY (key1,key2);

USING

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

'collected'

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

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

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

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

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

'merge'

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

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

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

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

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

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

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

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

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

PARTITION BY partitioner

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

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

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

PARALLEL n

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

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

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

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

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

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

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

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

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

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

B = GROUP A BY age;

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

ILLUSTRATE B;
etc ... 
----------------------------------------------------------------------
| B     | group: int | A: bag({name: chararray,age: int,gpa: float}) |
----------------------------------------------------------------------
|       | 18         | {(John, 18, 4.0), (Joe, 18, 3.8)}             |
|       | 20         | {(Bill, 20, 3.9)}                             |
----------------------------------------------------------------------

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

Далее, как показано в этих операторах FOREACH, мы можем ссылаться на поля в отношении B по именам "group" и "A" или с использованием позиционной нотации.

C = FOREACH B GENERATE group, COUNT(A);

DUMP C;
(18,2L)
(19,1L)
(20,1L)

C = FOREACH B GENERATE $0, $1.name;

DUMP C;
(18,{(John),(Joe)})
(19,{(Mary)})
(20,{(Bill)})

Пример

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

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

DUMP A;
(r1,1,2)
(r2,2,1)
(r3,2,8)
(r4,4,4)

В этом примере кортежи сгруппированы с использованием выражения f2*f3.

X = GROUP A BY f2*f3;

DUMP X;
(2,{(r1,1,2),(r2,2,1)})
(16,{(r3,2,8),(r4,4,4)})

Пример

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

A = LOAD 'data1' AS (owner:chararray,pet:chararray);

DUMP A;
(Alice,turtle)
(Alice,goldfish)
(Alice,cat)
(Bob,dog)
(Bob,cat)

B = LOAD 'data2' AS (friend1:chararray,friend2:chararray);

DUMP B;
(Cindy,Alice)
(Mark,Alice)
(Paul,Bob)
(Paul,Jane)

В этом примере кортежи когруппируются, используя поле «owner» из реляции A и поле «friend2» из реляции B в качестве ключевых полей. Оператор DESCRIBE показывает схему реляции X, которая имеет три поля: «group», «A» и «B» (см. оператор GROUP для получения информации об именах полей).

X = COGROUP A BY owner, B BY friend2;

DESCRIBE X;
X: {group: chararray,A: {owner: chararray,pet: chararray},B: {friend1: chararray,friend2: chararray}}

Реляция X выглядит следующим образом. Кортеж создается для каждого уникального ключевого поля. Кортеж включает ключевое поле и два мешка. Первый мешок содержит кортежи из первой реляции с соответствующим ключевым полем. Второй мешок содержит кортежи из второй реляции с соответствующим ключевым полем. Если кортежи не соответствуют ключевому полю, мешок пуст.

(Alice,{(Alice,turtle),(Alice,goldfish),(Alice,cat)},{(Cindy,Alice),(Mark,Alice)})
(Bob,{(Bob,dog),(Bob,cat)},{(Paul,Bob)})
(Jane,{},{(Paul,Jane)})

Пример

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

 A = LOAD 'allresults' USING PigStorage() AS (tcid:int, tpid:int, date:chararray, result:chararray, tsid:int, tag:chararray);
 B = GROUP A BY (tcid, tpid); 

Пример: PARTITION BY

Для использования Hadoop Partitioner добавьте клаузу PARTITION BY к соответствующему оператору:

A = LOAD 'input_data'; 
B = GROUP A BY $0 PARTITION BY org.apache.pig.test.utils.SimpleCustomPartitioner PARALLEL 2;

Вот код для SimpleCustomPartitioner:

public class SimpleCustomPartitioner extends Partitioner <PigNullableWritable, Writable> { 
     //@Override 
    public int getPartition(PigNullableWritable key, Writable value, int numPartitions) { 
        if(key.getValueAsPigType() instanceof Integer) { 
            int ret = (((Integer)key.getValueAsPigType()).intValue() % numPartitions); 
            return ret; 
       } 
       else { 
            return (key.hashCode()) % numPartitions; 
        } 
    } 
}

IMPORT

См. IMPORT (макросы)

JOIN (внутреннее)

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

Синтаксис

alias = JOIN alias BY {expression|'('expression [, expression …]')'} (, alias BY {expression|'('expression [, expression …]')'} …) [USING 'replicated' | 'skewed' | 'merge' | 'merge-sparse'] [PARTITION BY partitioner] [PARALLEL n];

Термины

alias

Имя реляции.

BY

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

expression

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

Пример: X = JOIN A BY fieldA, B BY fieldB, C BY fieldC;

USING

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

'replicated'

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

'skewed'

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

'merge'

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

'merge-sparse'

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

PARTITION BY partitioner

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

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

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

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

PARALLEL n

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

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

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

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

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

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

  • Операторы GROUP/COGROUP и JOIN обрабатывают нулевые значения по-разному (см. Нулевые значения и оператор JOIN).

Самосоединения

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

В этом примере одни и те же данные загружаются дважды с помощью псевдонимов A и B.

grunt> A = load 'mydata';
grunt> B = load 'mydata';
grunt> C = join A by $0, B by $0;
grunt> explain C;

Пример

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

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

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

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

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

В этом примере реляции A и B соединяются по их первым полям.

X = JOIN A BY a1, B BY b1;

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

JOIN (внешнее)

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

Синтаксис

alias = JOIN left-alias BY left-alias-column [LEFT|RIGHT|FULL] [OUTER], right-alias BY right-alias-column [USING 'replicated' | 'skewed' | 'merge'] [PARTITION BY partitioner] [PARALLEL n];

Термины

alias

Имя реляции. Применимо к alias, left-alias и right-alias.

alias-column

Имя столбца соединения для соответствующей реляции. Применимо к left-alias-column и right-alias-column.

BY

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

LEFT

Левое внешнее соединение.

RIGHT

Правое внешнее соединение.

FULL

Полное внешнее соединение.

OUTER

(Необязательно) Ключевое слово

USING

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

'replicated'

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

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

'skewed'

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

'merge'

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

PARTITION BY partitioner

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

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

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

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

PARALLEL n

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

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

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

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

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

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

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

Примеры

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

A = LOAD 'a.txt' AS (n:chararray, a:int); 
B = LOAD 'b.txt' AS (n:chararray, m:chararray);
C = JOIN A by $0 LEFT OUTER, B BY $0;

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

A = LOAD 'a.txt' AS (n:chararray, a:int); 
B = LOAD 'b.txt' AS (n:chararray, m:chararray);
C = JOIN A BY $0 FULL, B BY $0;

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

A = LOAD 'large';
B = LOAD 'tiny';
C= JOIN A BY $0 LEFT, B BY $0 USING 'replicated';

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

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

LIMIT

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

Синтаксис

alias = LIMIT alias n;

Термины

alias

Имя реляции.

n

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

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

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

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

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

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

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

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

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

Примеры

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

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

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

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

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

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

X = LIMIT A 3;

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

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

B = ORDER A BY f1 DESC, f2 ASC;

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

X = LIMIT B 3;

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

LOAD

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

Синтаксис

LOAD 'data' [USING function] [AS schema];

Термины

'data'

Имя файла или каталога, заключённое в одинарные кавычки.

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

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

Примечание: Pig использует Hadoop globbing, поэтому функциональность идентична. Однако, при запуске из командной строки с помощью команды Hadoop fs (а не оператора Pig LOAD), оболочка Unix может выполнить некоторые подстановки; это может изменить результат, создав впечатление, что globbing работает по-разному для Pig и Hadoop. Например:

  • Это работает
    hadoop fs -ls /mydata/20110423{00,01,02,03,04,05,06,07,08,09,{10..23}}00//part
  • Это не работает
    LOAD '/mydata/20110423{00,01,02,03,04,05,06,07,08,09,{10..23}}00//part '

USING

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

Если опустить предложение USING, используется функция по умолчанию PigStorage.

function

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

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

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

AS

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

schema

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

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

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

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

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

Примеры

Предположим, у нас есть файл данных с именем myfile.txt. Поля разделены табуляцией. Записи разделены символами новой строки.

1 2 3
4 2 1
8 3 4

В этом примере функция загрузки по умолчанию, PigStorage, загружает данные из myfile.txt, чтобы сформировать отношение A. Два оператора LOAD эквивалентны. Обратите внимание, что, поскольку схема не указана, поля не имеют имён, и все поля по умолчанию имеют тип bytearray.

A = LOAD 'myfile.txt';

A = LOAD 'myfile.txt' USING PigStorage('\t');

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

В этом примере схема указана с помощью ключевого слова AS. Два оператора LOAD эквивалентны. Вы можете использовать операторы DESCRIBE и ILLUSTRATE для просмотра схемы.

A = LOAD 'myfile.txt' AS (f1:int, f2:int, f3:int);

A = LOAD 'myfile.txt' USING PigStorage(‘\t’) AS (f1:int, f2:int, f3:int);

DESCRIBE A;
a: {f1: int,f2: int,f3: int}

ILLUSTRATE A;
---------------------------------------------------------
| a     | f1: bytearray | f2: bytearray | f3: bytearray |
---------------------------------------------------------
|       | 4             | 2             | 1             |
---------------------------------------------------------

---------------------------------------
| a     | f1: int | f2: int | f3: int |
---------------------------------------
|       | 4       | 2       | 1       |
---------------------------------------

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

MAPREDUCE

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

Синтаксис

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

Термины

alias1, alias2

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

mr.jar

Файл jar MapReduce (заключённый в одинарные кавычки).

Можно указать любой файл jar MapReduce, который может быть запущен с помощью команды hadoop jar mymr.jar params.

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

STORE ... INTO ... USING

См. STORE

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

LOAD ... USING ... AS

См. LOAD

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

`params, ...`

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

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

Используйте оператор MAPREDUCE для запуска собственных заданий MapReduce изнутри скрипта Pig.

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

Пример

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

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

ORDER BY

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

Синтаксис

alias = ORDER alias BY { * [ASC|DESC] | field_alias [ASC|DESC] [, field_alias [ASC|DESC] …] } [PARALLEL n];

Термины

alias

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

*

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

field_alias

Поле в отношении. Поле должно быть простым типом.

ASC

Сортировка по возрастанию.

DESC

Сортировка по убыванию.

PARALLEL n

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

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

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

Примечание: ORDER BY НЕ является стабильным; если несколько записей имеют одинаковый ключ ORDER BY, порядок, в котором эти записи возвращаются, не определён и не гарантируется, что он будет одинаковым при каждом запуске.

В Pig отношения не упорядочены (см. Отношения, множества, кортежи, поля):

  • Если вы упорядочиваете отношение A для создания отношения X (X = ORDER A BY * DESC;) отношения A и X по-прежнему содержат одни и те же данные.

  • Если вы получаете отношение X (DUMP X;), данные гарантированно будут в указанном порядке (по убыванию).

  • Однако, если вы дополнительно обрабатываете отношение X (Y = FILTER X BY $0 > 1;), нет никакой гарантии, что данные будут обрабатываться в исходном указанном порядке (по убыванию).

Pig в настоящее время поддерживает сортировку по полям с простыми типами или по обозначению кортежа (*). Нельзя сортировать по полям со сложными типами или по выражениям.

A = LOAD 'mydata' AS (x: int, y: map[]);     
B = ORDER A BY x; -- this is allowed because x is a simple type
B = ORDER A BY y; -- this is not allowed because y is a complex type
B = ORDER A BY y#'id'; -- this is not allowed because y#'id' is an expression

Примеры

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

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

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

В этом примере отношение A сортируется по третьему полю, f3, в порядке убывания. Обратите внимание, что порядок трёх кортежей, заканчивающихся на 3, может изменяться.

X = ORDER A BY a3 DESC;

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

RANK

Возвращает каждый кортеж с рангом в рамках отношения.

Синтаксис

alias = RANK alias [ BY { * [ASC|DESC] | field_alias [ASC|DESC] [, field_alias [ASC|DESC] …] } [DENSE] ];

Термины

alias

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

*

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

field_alias

Поле в отношении. Поле должно быть простым типом.

ASC

Сортировка по возрастанию.

DESC

Сортировка по убыванию.

DENSE

Без разрывов в значениях рангов.

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

При отсутствии поля для сортировки оператор RANK просто добавляет последовательное значение к каждому кортежу.

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

ПРИМЕЧАНИЕ: При использовании опции DENSE, совпадения не приводят к разрывам в значениях рангов.

Примеры

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

A = load 'data' AS (f1:chararray,f2:int,f3:chararray);
   
DUMP A;
(David,1,N)
(Tete,2,N)
(Ranjit,3,M)
(Ranjit,3,P)
(David,4,Q)
(David,4,Q)
(Jillian,8,Q)
(JaePak,7,Q)
(Michael,8,T)
(Jillian,8,Q)
(Jose,10,V)
            

В этом примере оператор RANK не изменяет порядок отношения и просто добавляет к каждому кортежу последовательное значение.

B = rank A;

dump B;
(1,David,1,N)
(2,Tete,2,N)
(3,Ranjit,3,M)
(4,Ranjit,3,P)
(5,David,4,Q)
(6,David,4,Q)
(7,Jillian,8,Q)
(8,JaePak,7,Q)
(9,Michael,8,T)
(10,Jillian,8,Q)
(11,Jose,10,V)
            

В этом примере оператор RANK работает с полями f1 и f2, и каждое с различным порядком сортировки. RANK сортирует отношение по этим полям и добавляет значение ранга к каждому кортежу. В противном случае оператор RANK использует каждое поле (или набор полей) для сортировки отношения. Ранг кортежа — это значение, на единицу большее, чем количество различных значений ранга, предшествующих ему. Если два или более кортежа совпадают по значениям сортировочного поля, они получат одинаковый ранг.

C = rank A by f1 DESC, f2 ASC;
                                
dump C;
(1,Tete,2,N)
(2,Ranjit,3,M)
(2,Ranjit,3,P)
(4,Michael,8,T)
(5,Jose,10,V)
(6,Jillian,8,Q)
(6,Jillian,8,Q)
(8,JaePak,7,Q)
(9,David,1,N)
(10,David,4,Q)
(10,David,4,Q)                
            

Тот же пример, что и ранее, но DENSE. В этом случае разрывов в значениях рангов нет.

C = rank A by f1 DESC, f2 ASC DENSE;

dump C;
(1,Tete,2,N)
(2,Ranjit,3,M)
(2,Ranjit,3,P)
(3,Michael,8,T)
(4,Jose,10,V)
(5,Jillian,8,Q)
(5,Jillian,8,Q)
(6,JaePak,7,Q)
(7,David,1,N)
(8,David,4,Q)
(8,David,4,Q)
            

SAMPLE

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

Синтаксис

SAMPLE alias size;

Термины

alias

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

size

Размер выборки, может быть

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

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

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

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

Пример

В этом примере отношение X будет содержать 1% данных из отношения A.

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

X = SAMPLE A 0.01;

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

a = load 'a.txt';
b = group a all;
c = foreach b generate COUNT(a) as num_rows;
e = sample a 1000/c.num_rows;

SPLIT

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

Синтаксис

SPLIT alias INTO alias IF expression, alias IF expression [, alias IF expression …] [, alias OTHERWISE];

Термины

alias

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

INTO

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

IF

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

expression

Выражение.

OTHERWISE

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

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

Используйте оператор SPLIT для разделения содержимого отношения на два или более отношений на основе некоторого выражения. В зависимости от условий, указанных в выражении:

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

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

Пример

В этом примере отношение A разделяется на три отношения: X, Y и Z.

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

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

SPLIT A INTO X IF f1<7, Y IF f2==5, Z IF (f3<6 OR f3>6);

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

DUMP Y;
(4,5,6)

DUMP Z;
(1,2,3)
(7,8,9)

Пример

В этом примере операторы SPLIT и FILTER по существу эквивалентны. Однако, поскольку SPLIT реализован как «разделение потока данных, а затем применение фильтров», оператор SPLIT дороже, чем оператор FILTER, поскольку Pig должен отфильтровать и сохранить два потока данных.

SPLIT input_var INTO output_var IF (field1 is not null), ignored_var IF (field1 is null);  
-- where ignored_var is not used elsewhere
   
output_var = FILTER input_var BY (field1 is not null);
   

STORE

Сохраняет результаты в файловой системе.

Синтаксис

STORE alias INTO 'directory' [USING function];

Термины

alias

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

INTO

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

'directory'

Имя каталога хранения в кавычках. Если каталог уже существует, операция STORE завершится с ошибкой.

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

USING

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

Если пункт USING опущен, используется функция сохранения PigStorage по умолчанию.

function

Функция сохранения.

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

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

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

Используйте оператор STORE для выполнения (исполнения) операторов Pig Latin и сохранения (сохранения) результатов в файловой системе. Используйте STORE для скриптов в рабочей среде и обработки в пакетном режиме.

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

Примеры

В этом примере данные сохраняются с помощью PigStorage и символа звездочка (*) в качестве разделителя полей.

A = LOAD 'data' AS (a1:int,a2:int,a3:int);

DUMP A;
(1,2,3)
(4,2,1)
(8,3,4)
(4,3,3)
(7,2,5)
(8,4,3)

STORE A INTO 'myoutput' USING PigStorage ('*');

CAT myoutput;
1*2*3
4*2*1
8*3*4
4*3*3
7*2*5
8*4*3

В этом примере используется функция CONCAT для форматирования данных перед их сохранением.

A = LOAD 'data' AS (a1:int,a2:int,a3:int);

DUMP A;
(1,2,3)
(4,2,1)
(8,3,4)
(4,3,3)
(7,2,5)
(8,4,3)

B = FOREACH A GENERATE CONCAT('a:',(chararray)f1), CONCAT('b:',(chararray)f2), CONCAT('c:',(chararray)f3);

DUMP B;
(a:1,b:2,c:3)
(a:4,b:2,c:1)
(a:8,b:3,c:4)
(a:4,b:3,c:3)
(a:7,b:2,c:5)
(a:8,b:4,c:3)

STORE B INTO 'myoutput' using PigStorage(',');

CAT myoutput;
a:1,b:2,c:3
a:4,b:2,c:1
a:8,b:3,c:4
a:4,b:3,c:3
a:7,b:2,c:5
a:8,b:4,c:3

STREAM

Отправляет данные во внешнюю скрипт или программу.

Синтаксис

alias = STREAM alias [, alias …] THROUGH {`command` | cmd_alias } [AS schema] ;

Термины

alias

Имя отношения.

THROUGH

Ключевое слово.

`command`

Команда, включая аргументы, заключенные в обратные кавычки (где команда — это все, что можно выполнить).

cmd_alias

Имя команды, созданной с помощью оператора DEFINE (см. DEFINE (UDFs, потоковая передача) для дополнительных примеров потоковой передачи).

AS

Ключевое слово.

schema

Схема, использующая ключевое слово AS, заключенная в скобки (см. Схемы).

Использование

Используйте оператор STREAM для передачи данных через внешнюю скрипт или программу. В одном скрипте Pig может быть несколько операторов stream. Операторы 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;

О гарантиях данных

Гарантии данных определяются на основе положения оператора потоковой передачи в скрипте Pig.

  • Неупорядоченные данные — нет гарантии порядка, в котором данные передаются приложению для потоковой передачи.

  • Сгруппированные данные — данные для одного и того же ключа группировки гарантированно предоставляются приложению для потоковой передачи непрерывно.

  • Сгруппированные и упорядоченные данные — данные для одного и того же ключа группировки гарантированно предоставляются приложению для потоковой передачи непрерывно. Кроме того, данные внутри группы гарантированно отсортированы по предоставленному второму ключу.

Помимо положения, группировка и упорядочивание данных могут быть определены самими данными. Однако вам необходимо знать свойства данных, чтобы использовать их структуру.

Пример: Гарантии данных

В этом примере данные неупорядочены.

A = LOAD 'data';

B = STREAM A THROUGH `stream.pl`;

В этом примере данные сгруппированы.

A = LOAD 'data';

B = GROUP A BY $1;

C = FOREACH B FLATTEN(A);

D = STREAM C THROUGH `stream.pl`;

В этом примере данные сгруппированы и упорядочены.

A = LOAD 'data';

B = GROUP A BY $1;

C = FOREACH B {
      D = ORDER A BY ($3, $4);
      GENERATE D;
}

E = STREAM C THROUGH `stream.pl`;

Пример: Схемы

В этом примере схема указана в операторе STREAM.

X = STREAM A THROUGH `stream.pl` as (f1:int, f2:int, f3:int);

UNION

Вычисляет объединение двух или более отношений.

Синтаксис

alias = UNION [ONSCHEMA] alias, alias [, alias …];

Термины

alias

Имя отношения.

ONSCHEMA

Используйте пункт ONSCHEMA для базы объединения на именованных полях (а не позиционную запись). Все входные данные для объединения должны иметь не-неизвестную (не-пустую) схему.

Использование

Используйте оператор UNION для объединения содержимого двух или более отношений. Оператор UNION:

  • Не сохраняет порядок кортежей. И входное, и выходное отношения интерпретируются как неупорядоченные наборы кортежей.

  • Не гарантирует (как это делают базы данных), что все кортежи следуют одной схеме или что они имеют одинаковое количество полей. Однако в типичном случае это должно быть так; поэтому ответственность пользователя заключается в том, чтобы либо (1) гарантировать, что кортежи во входных отношениях имеют одну и ту же схему, или (2) иметь возможность обрабатывать различные кортежи в выходном отношении.

  • Не исключает повторяющихся кортежей.

Поведение схемы

Поведение схем для UNION (позиционная запись / типы данных) и UNION ONSCHEMA (именованные поля / типы данных) одинаково, за исключением случаев, указанных ниже.

Объединение отношений с разными размерами приводит к схеме null (только объединение):

A: (a1:long, a2:long) 
B: (b1:long, b2:long, b3:long) 
A union B: null 

Объединение столбцов с несовместимыми типами приводит к типу bytearray:

A: (a1:long, a2:long) 
B: (b1:(b11:long, b12:long), b2:long) 
A union B: (a1:bytearray, a2:long) 

Объединение столбцов совместимого типа приведет к типу "escalate". Приоритет:

  • double > float > long > int > bytearray
  • tuple|bag|map|chararray > bytearray
A: (a1:int, a2:bytearray, a3:int) 
B: (b1:float, b2:chararray, b3:bytearray) 
A union B: (a1:float, a2:chararray, a3:int) 

Объединение различных внутренних типов приводит к пустому сложному типу:

A: (a1:(a11:long, a12:int), a2:{(a21:charray, a22:int)}) 
B: (b1:(b11:int, b12:int), b2:{(b21:int, b22:int)}) 
A union B: (a1:(), a2:{()}) 

Имя первого отношения всегда используется как имя поля объединённого отношения.

Пример

В этом примере вычисляется объединение отношения A и B.

A = LOAD 'data' AS (a1:int,a2:int,a3:int);

DUMP A;
(1,2,3)
(4,2,1)

B = LOAD 'data' AS (b1:int,b2:int);

DUMP A;
(2,4)
(8,9)
(1,3)

X = UNION A, B;

DUMP X;
(1,2,3)
(4,2,1)
(2,4)
(8,9)
(1,3)

Пример

В этом примере показано использование ONSCHEMA.

L1 = LOAD 'f1' USING (a : int, b : float);
DUMP L1;
(11,12.0)
(21,22.0)

L2 = LOAD  'f1' USING (a : long, c : chararray);
DUMP L2;
(11,a)
(12,b)
(13,c)

U = UNION ONSCHEMA L1, L2;
DESCRIBE U ;
U : {a : long, b : float, c : chararray}

DUMP U;
(11,12.0,)
(21,22.0,)
(11,,a)
(12,,b)
(13,,c)

УФ-операторы

ОПРЕДЕЛИТЬ (UDFs, потоковая обработка)

Присваивает псевдоним UDF или команде потоковой обработки.

Синтаксис: UDF и потоковая обработка

ОПРЕДЕЛИТЬ псевдоним {функция | [`команда` [вход] [выход] [пересылка] [кеширование] [ошибка] ] };

Термины

псевдоним

Имя функции UDF или имя команды потоковой обработки (cmd_alias для оператора ПОТОК).

функция

Для использования с функциями.

Имя функции UDF.

`команда`

Для использования с потоковой обработкой.

Команда, включая аргументы, заключённые в обратные кавычки (любая команда, которую можно выполнить).

Описания положений (вход, выход, пересылка, кеширование, ошибка) представлены ниже. Обратите внимание на следующее:

  • Все положения необязательны.
  • Положения могут быть указаны в любом порядке (например, ошибка может быть указана до входа).
  • Каждое положение может быть указано не более одного раза (например, несколько входов не допускаются).

вход

Для использования с потоковой обработкой.

ВХОД ( {stdin | 'путь'} [ИСПОЛЬЗУЯ сериализатор] [, {stdin | 'путь'} [ИСПОЛЬЗУЯ сериализатор] …] )

Где:

  • ВХОД – Ключевое слово.

  • 'путь' – Путь к файлу, заключённый в одинарные кавычки.

  • ИСПОЛЬЗУЯ – Ключевое слово.

  • сериализатор – PigStreaming – это сериализатор по умолчанию.

выход

Для использования с потоковой обработкой.

ВЫХОД ( {stdout | stderr | 'путь'} [ИСПОЛЬЗУЯ десериализатор] [, {stdout | stderr | 'путь'} [ИСПОЛЬЗУЯ десериализатор] …] )

Где:

  • ВЫХОД – Ключевое слово.

  • 'путь' – Путь к файлу, заключённый в одинарные кавычки.

  • ИСПОЛЬЗУЯ – Ключевое слово.

  • десериализатор – PigStreaming – это десериализатор по умолчанию.

пересылка

Для использования с потоковой обработкой.

ПЕРЕСЫЛКА('путь' [, 'путь' …])

Где:

  • ПЕРЕСЫЛКА – Ключевое слово.

  • 'путь' – Путь к файлу, заключённый в одинарные кавычки.

кеширование

Для использования с потоковой обработкой.

КЕШИРОВАНИЕ('путь_в_dfs#имя_файла' [, 'путь_в_dfs#имя_файла' …])

Где:

  • КЕШИРОВАНИЕ – Ключевое слово.

  • 'путь_в_dfs#имя_файла' – Путь к файлу/имя файла в распределённой файловой системе, заключённый в одинарные кавычки. Пример: '/mydir/mydata.txt#mydata.txt'

ошибка

Для использования с потоковой обработкой.

STDERR( '/каталог') или STDERR( '/каталог' ОГРАНИЧЕНИЕ n)

Где:

  • '/каталог' – каталог логов, заключённый в одинарные кавычки.
  • (необязательно) ОГРАНИЧЕНИЕ n – порог ошибок, где n – целое число. Если не указано, порог ошибок не ограничен.

Использование

Используйте оператор ОПРЕДЕЛИТЬ, чтобы присвоить имя (псевдоним) функции UDF или команде потоковой обработки.

Используйте ОПРЕДЕЛИТЬ для задания функции UDF, когда:

  • Функция имеет длинное имя пакета, которое вы не хотите включать в скрипт, особенно если вы вызываете функцию несколько раз в этом скрипте.

  • Конструктор функции принимает строковые параметры. Если вам нужно использовать разные параметры конструктора для разных вызовов функции, вам необходимо создать несколько определений – по одному для каждого набора параметров.

Используйте ОПРЕДЕЛИТЬ для задания команды потоковой обработки, когда:

  • Спецификация команды потоковой обработки сложная.

  • Спецификация команды потоковой обработки требует дополнительных параметров (вход, выход и т. д.).

О вводе и выводе

Необходимо использовать сериализацию для преобразования данных из кортежей в формат, который может обрабатываться приложением потоковой обработки. Необходимо использовать десериализацию для преобразования вывода приложения потоковой обработки обратно в кортежи. PigStreaming — это функция сериализации/десериализации по умолчанию.

Потоковая обработка использует тот же формат по умолчанию, что и PigStorage, для сериализации/десериализации данных. Если вы хотите явно указать формат, вы можете сделать это, как показано ниже (см. дополнительные примеры в разделе Примеры: Вход/Выход).

DEFINE CMD `perl PigStreaming.pl - nameMap` input(stdin using PigStreaming(',')) output(stdout using PigStreaming(','));
A = LOAD 'file';
B = STREAM B THROUGH CMD;

Если вам нужен альтернативный формат, вам необходимо создать пользовательскую функцию сериализации/десериализации, реализовав следующие интерфейсы.

interface PigToStream {

    /**
     * Given a tuple, produce an array of bytes to be passed to the streaming
     * executable.
     */
    public byte[] serialize(Tuple t) throws IOException;
}

interface StreamToPig {

    /**
     *  Given a byte array from a streaming executable, produce a tuple.
     */
    public Tuple deserialize(byte[]) throws IOException;

    /**
     * This will be called on the front end during planning and not on the back
     * end during execution.
     *
     * @return the {@link LoadCaster} associated with this object.
     * @throws IOException if there is an exception during LoadCaster
     */
    public LoadCaster getLoadCaster() throws IOException;
}
О пересылке

Используйте опцию пересылки, чтобы отправлять двоичные данные потоковой обработки и, при необходимости, вспомогательные файлы с узла клиента на узлы вычислений. Pig не выполняет автоматическую пересылку зависимостей; вы сами должны явно указать все зависимости и убедиться, что программное обеспечение, на котором основана обработка (например, perl или python), установлено в кластере. Вспомогательные файлы пересылаются в текущую рабочую директорию задачи, и следует указывать только относительные пути. Любые предварительно установленные двоичные файлы должны быть указаны в переменной среды PATH.

С помощью опции пересылки можно указать только файлы, а не каталоги. Один из способов обойти это ограничение — заархивировать все зависимости в файл tar, точно отражающий необходимую структуру на узлах вычислений, а затем использовать оболочку для вашего скрипта, которая распаковывает зависимости перед выполнением.

Обратите внимание, что опция пересылки имеет две составляющие: спецификация источника, предоставленная в предложении ship(), отражает вашу машину; спецификация команды отражает фактический кластер. Единственная гарантия заключается в том, что пересылаемые файлы доступны в текущей рабочей директории запущенной задачи и что текущая рабочая директория также присутствует в переменной среды PATH.

Пересылка файлов по относительным или абсолютным путям не поддерживается, так как у вас могут не быть разрешений на чтение/запись/выполнение из произвольных путей в кластерах.

Обратите внимание на следующее:

  • Безопасно пересылать файлы только для выполнения из текущей рабочей директории задачи в кластере.

    OP = stream IP through 'script';
    or
    DEFINE CMD 'script' ship('/a/b/script');
    OP = stream IP through CMD;
    
  • Пересылка файлов по относительным или абсолютным путям не определена и в большинстве случаев завершится неудачно, поскольку у вас могут не быть разрешений на чтение/запись/выполнение из произвольных путей на фактических кластерах.

О кэшировании

Опция пересылки работает с двоичными файлами, jar-файлами и небольшими наборами данных. Однако загрузка больших наборов данных во время выполнения для каждого выполнения может существенно повлиять на производительность. Вместо этого используйте опцию кэширования для доступа к большим файлам, которые уже перемещены и доступны на узлах вычислений. С помощью опции кэширования можно указать только файлы, а не каталоги.

О автоматической пересылке

Если опции пересылки и кэширования не указаны, Pig попытается выполнить автоматическую пересылку двоичного файла следующим образом:

  • Если первое слово в команде потоковой обработки — perl или python, Pig предполагает, что двоичный файл — это первая нецитируемая строка, которая не начинается с тире.

  • В противном случае Pig попытается переслать первую строку из командной строки, пока она не поступает из /bin, /usr/bin, /usr/local/bin. Pig определит это, просканировав путь, если указан абсолютный путь, или выполнив which. Пути можно сделать настраиваемыми с помощью параметра set stream.skippath (вы можете использовать несколько команд set для задания более одного пути для пропуска).

Если вы не укажите ОПРЕДЕЛИТЬ для данной команды потоковой обработки, автоматическая пересылка выключена.

Обратите внимание на следующее:

  • Если Pig определит, что ему необходимо выполнить автоматическую пересылку абсолютного пути, он не будет пересылать его вообще, так как нет способа переслать файлы в необходимое место (отсутствие разрешений и т. д.).

    OP = stream IP through `/a/b/c/script`;
    or 
    OP = stream IP through `perl /a/b/c/script.pl`;
    
  • Pig не будет выполнять автоматическую пересылку файлов в следующих системных каталогах (это определяется выполнением команды 'which <файл>' ).

    /bin /usr/bin /usr/local/bin /sbin /usr/sbin /usr/local/sbin
    
  • Для автоматической пересылки файл должен присутствовать в переменной среды PATH. Таким образом, если файл находится в текущей рабочей директории, текущая рабочая директория должна быть в переменной среды PATH.

Примеры: Вход/Выход

В этом примере PigStreaming — это функция сериализации/десериализации по умолчанию. Кортежи из отношения A преобразуются в строки с разделителем «табуляция», которые передаются в скрипт.

X = STREAM A THROUGH `stream.pl`;

В этом примере PigStreaming используется в качестве функции сериализации/десериализации, но в качестве разделителя используется запятая.

DEFINE Y 'stream.pl' INPUT(stdin USING PigStreaming(',')) OUTPUT (stdout USING PigStreaming(','));

X = STREAM A THROUGH Y;

В этом примере используются пользовательские функции сериализации/десериализации со скриптом.

DEFINE Y 'stream.pl' INPUT(stdin USING MySerializer) OUTPUT (stdout USING MyDeserializer);

X = STREAM A THROUGH Y;

Примеры: Пересылка/Кэширование

В этом примере используется пересылка для отправки скрипта на узлы вычислений кластера.

DEFINE Y 'stream.pl' SHIP('/work/stream.pl');

X = STREAM A THROUGH Y;

В этом примере используется кэширование для указания файла, расположенного на узлах вычислений кластера.

DEFINE Y 'stream.pl data.gz' SHIP('/work/stream.pl') CACHE('/input/data.gz#data.gz');

X = STREAM A THROUGH Y;

Пример: ОПРЕДЕЛИТЬ с ПОТОКОМ

В этом примере команда определяется для использования с оператором ПОТОК.

A = LOAD 'data';

DEFINE mycmd 'stream_cmd –input file.dat';

B = STREAM A through mycmd;

Примеры: Ведение журнала

В этом примере ошибка потоковой обработки stderr сохраняется в каталоге _logs/<dir> каталога вывода задачи. Поскольку в задаче может быть несколько приложений потоковой обработки, необходимо убедиться, что используются различные имена каталогов, чтобы избежать конфликтов. Pig хранит до 100 задач на задачу потоковой обработки.

DEFINE Y 'stream.pl' stderr('<dir>' limit 100);

X = STREAM A THROUGH Y;

Примеры: ОПРЕДЕЛИТЬ функцию

В этом примере функция определяется для использования с оператором FOREACH …GENERATE.

REGISTER /src/myfunc.jar

DEFINE myFunc myfunc.MyEvalfunc('foo');

A = LOAD 'students';

B = FOREACH A GENERATE myFunc($0);

ЗАРЕГИСТРИРОВАТЬ

Регистрирует JAR-файл, чтобы функции UDF в этом файле можно было использовать.

Синтаксис

ЗАРЕГИСТРИРОВАТЬ путь;

Термины

путь

Путь к JAR-файлу (требуется полное URI расположения). Не заключайте имя в кавычки.

Использование

Скрипты Pig

Используйте оператор ЗАРЕГИСТРИРОВАТЬ внутри скрипта Pig для задания JAR-файла или модуля Python/JavaScript. Pig поддерживает JAR-файлы и модули, хранящиеся в локальных файловых системах, а также в удалённых распределённых файловых системах, таких как HDFS и Amazon S3 (см. Скрипты Pig).

Кроме того, JAR-файлы, хранящиеся в локальных файловых системах, могут быть указаны как шаблон glob с использованием «*». Pig будет искать соответствующие jar-файлы в локальной файловой системе, либо по относительному пути (относительно вашей рабочей директории), либо по абсолютному пути. Pig будет подбирать все JAR-файлы, соответствующие шаблону glob.

Командная строка

Вы можете зарегистрировать дополнительные файлы (для использования со скриптом Pig) через командную строку с помощью параметра -Dpig.additional.jars. Дополнительную информацию см. в разделе Пользовательские функции.

Примеры

В этом примере 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 -Dpig.additional.jars=my.jar:your.jar script.pig

В этом примере JAR-файл, хранящийся в HDFS, регистрируется.

pig -Dpig.additional.jars=hdfs://nn.mydomain.com:9020/myjars/my.jar script.pig

В этом примере показано, как указать шаблон glob, используя либо относительный, либо абсолютный путь.

register /homes/user/pig/myfunc*.jar
register count*.jar
register jars/*.jar

© 2007–2016 Apache Software Foundation
Licensed under the Apache Software License version 2.0.
https://pig.apache.org/docs/r0.13.0/basic.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API