The FOREACH...GENERATE statement is one of the most fundamental and frequently used operations in Pig Latin. It is the primary tool for projection (selecting columns) and transformation (modifying data) on a per-record basis.
1. Function: Projecting and Transforming
The command takes an input relation and applies a set of expressions (including simple field selection, functions, and calculations) to every single record (row) in that relation, resulting in a new output relation.
Projection: Selecting specific fields to include in the new relation.
Transformation: Applying functions, arithmetic, or logical operations to create new, modified, or derived fields.
2. Basic Projection Example
The first example shows simple projection, selecting only a subset of fields from the input relation A:
A = load 'input' as (user:chararray, id:long, address:chararray, phone:chararray, preferences:map[]);
B = foreach A generate user, id;
Input (A): Contains five fields (user, id, address, phone, preferences).
Operation: For every record in A, select the values for the user and id fields.
Output (B): A new relation containing only two fields: user and id.
3. Transformation and Field Referencing
The second example demonstrates using expressions to create new, calculated fields. You can reference fields either by name or by their position (index):
prices = load 'NYSE_daily' as (exchange, symbol, date, open, high, low, close, volume, adj_close);
gain = foreach prices generate close - open;
gain2 = foreach prices generate $6 - $3;
Field Name Reference (close - open):
gain is a new relation where each record is the result of subtracting the open price from the close price, which yields the daily price change. The resulting field will be automatically named $$1 unless you explicitly give it a name using AS (e.g., generate close - open AS daily_gain).
Positional Reference ($6 - $3):
Pig Latin allows you to reference fields by their 0-based index. In the prices schema:
$3 refers to the 4th field, open.
$6 refers to the 7th field, close.
The result in gain2 is identical to gain, showcasing two ways to achieve the same transformation. Using names is strongly recommended for script readability and maintainability.
The FOREACH...GENERATE statement is essentially the mechanism that executes all the Arithmetic, String, and Built-In Functions (like UPPER(), ROUND(), etc.) across the dataset.