Apache Pig 简明教程
Apache Pig - Overview
What is Apache Pig?
Apache Pig 是基于 MapReduce 的抽象。这是一种工具/平台,用于分析大数据集并将其表示为数据流。Pig 通常与 Hadoop 一起使用;我们可以使用 Apache Pig 在 Hadoop 中执行所有数据操作。
为了编写数据分析程序,Pig 提供了一种称为 Pig Latin 的高级语言。这种语言提供了各种运算符,程序员可以利用这些运算符为自己的数据读取、写入和处理函数进行编程。
为了使用 Apache Pig 分析数据,程序员需要使用 Pig Latin 语言编写脚本。所有这些脚本都会在内部转换为 Map 和 Reduce 任务。Apache Pig 有一个称为 Pig Engine 的组件,此组件接受 Pig Latin 脚本作为输入,并将这些脚本转换为 MapReduce 作业。
Why Do We Need Apache Pig?
那些不太精通 Java 的程序员通常会竭力尝试使用 Hadoop,尤其是在执行任何 MapReduce 任务的时候。Apache Pig 是所有该类程序员的福音。
-
使用 Pig Latin ,程序员无需使用 Java 编写复杂的代码,即可轻松执行 MapReduce 任务。
-
Apache Pig 使用 multi-query approach ,进而缩短了代码的长度。例如,可以用 Java 编写 200 行代码(LoC)来执行某项操作,而使用 Apache Pig 仅需编写 10 个以上的 LoC 即可轻松完成此操作。究其根本,Apache Pig 将开发时间缩短了将近 16 倍。
-
Pig Latin 是 SQL-like language ,如果你熟悉 SQL,学习 Apache Pig 会非常容易。
-
Apache Pig 提供了许多内置运算符来支持数据操作,例如连接、筛选、排序等。此外,它还提供了 MapReduce 中没有的嵌套数据类型,例如元组、包和映射。
Features of Pig
Apache Pig 具有以下功能 −
-
Rich set of operators − 它提供了许多运算符来执行诸如连接、排序、筛选等操作。
-
Ease of programming − Pig Latin 类似于 SQL,如果你精通 SQL,很容易编写 Pig 脚本。
-
Optimization opportunities − Apache Pig 中的任务会自动优化其执行,因此程序员只需要专注于该语言的语义。
-
Extensibility − 使用现有运算符,用户可以创建自己的函数来读取、处理和写入数据。
-
UDF’s − Pig 提供了创建 User-defined Functions 的功能 ,这些创建可以在诸如 Java 的其他编程语言中编写,并将它们调用或嵌入到 Pig 脚本中。
-
Handles all kinds of data − Apache Pig 分析所有类型的数据,既可以是结构化的,也可以是非结构化的。它将结果存储到 HDFS 中。
Apache Pig Vs MapReduce
下面列出了 Apache Pig 与 MapReduce 的主要区别。
Apache Pig |
MapReduce |
Apache Pig 是一种数据流语言。 |
MapReduce 是一种数据处理范例。 |
Apache Pig 是一种高级语言。 |
MapReduce 是低级且严格的。 |
在 Apache Pig 中执行连接操作非常简单。 |
在 MapReduce 中执行数据集之间的连接操作非常困难。 |
具有基本 SQL 知识的任何新手程序员都可以方便地使用 Apache Pig。 |
必须熟悉 Java 才能使用 MapReduce。 |
Apache Pig 使用多查询方法,从而在很大程度上减少了代码的长度。 |
MapReduce 将需要多达 20 倍的行数才能执行相同的任务。 |
无需编译。在执行时,每个 Apache Pig 运算符都会在内部转换为 MapReduce 作业。 |
MapReduce 作业具有很长的编译过程。 |
Apache Pig Vs SQL
下面列出了 Apache Pig 与 SQL 的主要区别。
Pig |
SQL |
Pig Latin 是 procedural 语言。 |
SQL 是 declarative 语言。 |
在 Apache Pig 中, schema 是可选的。我们可以在不设计模式的情况下存储数据(值存储为 $01、$02 等等)。 |
SQL 中模式是强制性的。 |
Apache Pig 中的数据模型是 nested relational 。 |
SQL 中使用的数据模型 is flat relational 。 |
Apache Pig 提供有限的机会进行 Query optimization 。 |
SQL 中有更多机会进行查询优化。 |
除以上差异之外,Apache Pig Latin −
-
允许管道中出现拆分。
-
允许开发人员在管道中任意位置存储数据。
-
Declares execution plans.
-
提供进行 ETL(提取、转换和加载)函数的操作符。
Apache Pig Vs Hive
Apache Pig 和 Hive 都用于创建 MapReduce 作业。在某些情况下,Hive 在 HDFS 上的操作方式类似于 Apache Pig。在以下表格中,我们列出了使 Apache Pig 区别于 Hive 的一些重要要点。
Apache Pig |
Hive |
Apache Pig 使用称为 Pig Latin 的语言。它最初是在 Yahoo 创建的。 |
Hive 使用称为 HiveQL 的语言。它最初是在 Facebook 创建的。 |
Pig Latin 是一种数据流语言。 |
HiveQL 是一种查询处理语言。 |
Pig Latin 是一种过程语言,符合管道范例。 |
HiveQL 是一种声明性语言。 |
Apache Pig 可以处理结构化、非结构化和半结构化数据。 |
Hive 主要用于结构化数据。 |
Apache Pig - Architecture
用于使用 Pig 在 Hadoop 中分析数据的语言称为 Pig Latin 。它是一种高级数据处理语言,提供了丰富的数据类型和运算符,用于对数据执行各种操作。
为了执行特定的任务,使用 Pig 的程序员需要使用 Pig Latin 语言编写 Pig 脚本,并使用任何执行机制(Grunt Shell、UDF、Embedded)来执行它们。执行后,这些脚本将经历 Pig Framework 应用的一系列转换,以产生所需的输出。
在内部,Apache Pig 将这些脚本转换成一系列 MapReduce 作业,因此,它使程序员的工作变得轻松。Apache Pig 的架构如下所示。
Apache Pig Components
如图所示,Apache Pig 框架中有各种组件。让我们了解主要组件。
Pig Latin Data Model
Pig Latin 的数据模型是完全嵌套的,允许复杂非原子数据类型,如 map 和 tuple 。以下是 Pig Latin 数据模型的图表表示。
Atom
在 Pig Latin 中,任何单一值,无论其数据类型如何,都称为 Atom 。它存储为字符串,可以用作字符串和数字。int、long、float、double、chararray 和 bytearray 是 Pig 的原子值。数据片段或简单原子值称为 field 。
Example − ‘raja’ 或 ‘30’
Bag
集合是元组的无序集。换句话说,元组的集合(非唯一)称为集合。每个元组可以有任意数量的字段(灵活架构)。集合用 “{}” 表示。它类似于 RDBMS 中的表,但与 RDBMS 中的表不同,并不是每个元组都必须包含相同数量的字段或同一位置(列)的字段具有相同的类型。
Example − {(Raja, 30), (Mohammad, 45)}
集合可以是关系中的一个字段;在这种情况下,它称为 inner bag 。
Example − {Raja, 30, {9848022338, raja@gmail.com,} }
Apache Pig - Installation
本章说明了如何下载、安装和在您的系统中设置 Apache Pig 。
Prerequisites
在使用 Apache Pig 之前,您必须在自己的系统上安装 Hadoop 和 Java 至关重要。因此,在安装 Apache Pig 之前,请按照以下链接中给出的步骤安装 Hadoop 和 Java −
Download Apache Pig
首先,从以下网站下载 Apache Pig 的最新版本 − https://pig.apache.org/
Install Apache Pig
下载 Apache Pig 软件后,请按照以下给定的步骤在 Linux 环境中安装它。
Step 1
在安装 Hadoop, Java, 和其他软件的安装目录所在的同一目录中创建一个名为 Pig 的目录。(在我们的教程中,我们在名为 Hadoop 的用户中创建了 Pig 目录)。
$ mkdir Pig
Configure Apache Pig
安装 Apache Pig 后,我们必须配置它。要配置,我们需要编辑两个文件 − bashrc and pig.properties 。
.bashrc file
在 .bashrc 文件中,设置以下变量 −
-
PIG_HOME 文件夹为 Apache Pig 的安装文件夹,
-
PATH 环境变量为 bin 文件夹,
-
PIG_CLASSPATH 环境变量为 Hadoop 安装的 etc(配置)文件夹(包含 core-site.xml、hdfs-site.xml 和 mapred-site.xml 文件的目录)。
export PIG_HOME = /home/Hadoop/Pig
export PATH = $PATH:/home/Hadoop/pig/bin
export PIG_CLASSPATH = $HADOOP_HOME/conf
pig.properties file
在 Pig 的 conf 文件夹中,有一个名为 pig.properties 的文件。在 pig.properties 文件中,您可以按照下面给出的方式,设置各种参数。
pig -h properties
支持以下属性 −
Logging: verbose = true|false; default is false. This property is the same as -v
switch brief=true|false; default is false. This property is the same
as -b switch debug=OFF|ERROR|WARN|INFO|DEBUG; default is INFO.
This property is the same as -d switch aggregate.warning = true|false; default is true.
If true, prints count of warnings of each type rather than logging each warning.
Performance tuning: pig.cachedbag.memusage=<mem fraction>; default is 0.2 (20% of all memory).
Note that this memory is shared across all large bags used by the application.
pig.skewedjoin.reduce.memusagea=<mem fraction>; default is 0.3 (30% of all memory).
Specifies the fraction of heap available for the reducer to perform the join.
pig.exec.nocombiner = true|false; default is false.
Only disable combiner as a temporary workaround for problems.
opt.multiquery = true|false; multiquery is on by default.
Only disable multiquery as a temporary workaround for problems.
opt.fetch=true|false; fetch is on by default.
Scripts containing Filter, Foreach, Limit, Stream, and Union can be dumped without MR jobs.
pig.tmpfilecompression = true|false; compression is off by default.
Determines whether output of intermediate jobs is compressed.
pig.tmpfilecompression.codec = lzo|gzip; default is gzip.
Used in conjunction with pig.tmpfilecompression. Defines compression type.
pig.noSplitCombination = true|false. Split combination is on by default.
Determines if multiple small files are combined into a single map.
pig.exec.mapPartAgg = true|false. Default is false.
Determines if partial aggregation is done within map phase, before records are sent to combiner.
pig.exec.mapPartAgg.minReduction=<min aggregation factor>. Default is 10.
If the in-map partial aggregation does not reduce the output num records by this factor, it gets disabled.
Miscellaneous: exectype = mapreduce|tez|local; default is mapreduce. This property is the same as -x switch
pig.additional.jars.uris=<comma seperated list of jars>. Used in place of register command.
udf.import.list=<comma seperated list of imports>. Used to avoid package names in UDF.
stop.on.failure = true|false; default is false. Set to true to terminate on the first error.
pig.datetime.default.tz=<UTC time offset>. e.g. +08:00. Default is the default timezone of the host.
Determines the timezone used to handle datetime datatype and UDFs.
Additionally, any Hadoop property can be specified.
Apache Pig - Execution
在上一个章节中,我们解释了如何安装 Apache Pig。在这个章节中,我们将讨论如何执行 Apache Pig。
Apache Pig Execution Mechanisms
Apache Pig 脚本可以通过以下三种方式执行:交互模式、批处理模式和嵌入模式。
-
Interactive Mode (Grunt Shell) − 您可以使用 Grunt Shell 以交互模式运行 Apache Pig。在此 Shell 中,您可以输入 Pig Latin 语句并获取输出(使用 Dump 操作符)。
-
Batch Mode (脚本) − 您可以通过使用 .pig 扩展名在单个文件中编写 Pig Latin 脚本,以批处理模式运行 Apache Pig。
-
Embedded Mode (UDF) − Apache Pig 提供在编程语言(例如 Java)中定义我们自己的函数(*U*ser *D*efined *F*unctions)并将其用于我们脚本中的服务。
Invoking the Grunt Shell
您可以使用 −x 选项,按所需模式(本地/MapReduce)调用 Grunt shell,如下所示。
Local mode |
MapReduce mode |
Command − $ ./pig –x local |
Command − $ ./pig -x mapreduce |
Output − |
Output − |
这两个命令中的任一个都将给你 Grunt shell 提示符,如下所示。
grunt>
你可以使用 ‘ctrl + d’. 退出 Grunt shell
在调用 Grunt shell 之后,你可以直接在其中输入 Pig Latin 语句子来执行 Pig 脚本。
grunt> customers = LOAD 'customers.txt' USING PigStorage(',');
Executing Apache Pig in Batch Mode
你可以将完整的 Pig Latin 脚本写到文件中,并使用 –x command 来执行它。假设我们在一个名为 sample_script.pig 的文件中有一个 Pig 脚本,如下所示。
Sample_script.pig
student = LOAD 'hdfs://localhost:9000/pig_data/student.txt' USING
PigStorage(',') as (id:int,name:chararray,city:chararray);
Dump student;
现在,你可以按照以下方式执行以上文件中的脚本。
Local mode |
MapReduce mode |
$ pig -x local Sample_script.pig |
$ pig -x mapreduce Sample_script.pig |
Note − 我们将在后续章节中详细讨论如何在 Bach mode 和 embedded mode 中运行 Pig 脚本。
Apache Pig - Grunt Shell
调用 Grunt shell 后,您可以在 shell 中运行 Pig 脚本。此外,Grunt shell 还提供了一些有用的 shell 和实用程序命令。本章介绍了 Grunt shell 提供的 shell 和实用程序命令。
Note − 在本章的某些部分中,会使用 Load 和 Store 等命令。参考相应章节以获取有关它们的详细信息。
Shell Commands
Apache Pig 的 Grunt shell 主要用于编写 Pig Latin 脚本。在编写脚本之前,我们可以使用 sh 和 fs 来调用任意 shell 命令。
sh Command
使用 grunt shell 的 sh 命令,我们可以调用任意 shell 命令。使用 grunt shell 的 sh 命令,我们不能执行 shell 环境的一部分命令( ex − cd)。
Syntax
下面给出了 sh 命令的语法:
grunt> sh shell command parameters
Example
我们可以使用 sh 选项,使用如下方式,从 grunts shell 调用 Linux shell 的 ls 命令。在这个例子中,它列出了 /pig/bin/ 目录中的文件。
grunt> sh ls
pig
pig_1444799121955.log
pig.cmd
pig.py
fs Command
使用 fs 命令,我们可以从 grunt shell 调用任意 FsShell 命令。
Syntax
下面给出了 fs 命令的语法:
grunt> sh File System command parameters
Example
我们可以使用 fs 命令,从 grunt shell 调用 HDFS 的 ls 命令。在下面的例子中,它列出了 HDFS 根目录中的文件。
grunt> fs –ls
Found 3 items
drwxrwxrwx - Hadoop supergroup 0 2015-09-08 14:13 Hbase
drwxr-xr-x - Hadoop supergroup 0 2015-09-09 14:52 seqgen_data
drwxr-xr-x - Hadoop supergroup 0 2015-09-08 11:30 twitter_data
同样的,我们可以使用 fs 命令,从 grunt shell 调用所有其他文件系统 shell 命令。
Utility Commands
Grunt shell 提供了一组实用程序命令。这些命令包括 like clear, help, history, quit, 和 set 的实用程序命令;还有 exec, kill, and run 等控制 grunt shell 的 Pig 命令。下面描述了 grunt shell 提供的实用程序命令。
clear Command
clear 命令用于清除 grunt shell 屏幕。
Syntax
您可以使用 clear 命令清除 grunt shell 屏幕,如下所示:
grunt> clear
help Command
help 命令给出 Pig 命令或 Pig 属性的列表。
Usage
您可以使用 help 命令获取 Pig 命令的列表,如下所示:
grunt> help
Commands: <pig latin statement>; - See the PigLatin manual for details:
http://hadoop.apache.org/pig
File system commands:fs <fs arguments> - Equivalent to Hadoop dfs command:
http://hadoop.apache.org/common/docs/current/hdfs_shell.html
Diagnostic Commands:describe <alias>[::<alias] - Show the schema for the alias.
Inner aliases can be described as A::B.
explain [-script <pigscript>] [-out <path>] [-brief] [-dot|-xml]
[-param <param_name>=<pCram_value>]
[-param_file <file_name>] [<alias>] -
Show the execution plan to compute the alias or for entire script.
-script - Explain the entire script.
-out - Store the output into directory rather than print to stdout.
-brief - Don't expand nested plans (presenting a smaller graph for overview).
-dot - Generate the output in .dot format. Default is text format.
-xml - Generate the output in .xml format. Default is text format.
-param <param_name - See parameter substitution for details.
-param_file <file_name> - See parameter substitution for details.
alias - Alias to explain.
dump <alias> - Compute the alias and writes the results to stdout.
Utility Commands: exec [-param <param_name>=param_value] [-param_file <file_name>] <script> -
Execute the script with access to grunt environment including aliases.
-param <param_name - See parameter substitution for details.
-param_file <file_name> - See parameter substitution for details.
script - Script to be executed.
run [-param <param_name>=param_value] [-param_file <file_name>] <script> -
Execute the script with access to grunt environment.
-param <param_name - See parameter substitution for details.
-param_file <file_name> - See parameter substitution for details.
script - Script to be executed.
sh <shell command> - Invoke a shell command.
kill <job_id> - Kill the hadoop job specified by the hadoop job id.
set <key> <value> - Provide execution parameters to Pig. Keys and values are case sensitive.
The following keys are supported:
default_parallel - Script-level reduce parallelism. Basic input size heuristics used
by default.
debug - Set debug on or off. Default is off.
job.name - Single-quoted name for jobs. Default is PigLatin:<script name>
job.priority - Priority for jobs. Values: very_low, low, normal, high, very_high.
Default is normal stream.skippath - String that contains the path.
This is used by streaming any hadoop property.
help - Display this message.
history [-n] - Display the list statements in cache.
-n Hide line numbers.
quit - Quit the grunt shell.
history Command
这个命令显示了自调用 grunt shell 以来执行/使用的语句列表。
Usage
假设我们在打开 grunt shell 以来执行了三条语句。
grunt> customers = LOAD 'hdfs://localhost:9000/pig_data/customers.txt' USING PigStorage(',');
grunt> orders = LOAD 'hdfs://localhost:9000/pig_data/orders.txt' USING PigStorage(',');
grunt> student = LOAD 'hdfs://localhost:9000/pig_data/student.txt' USING PigStorage(',');
然后,使用 history 命令将产生以下输出。
grunt> history
customers = LOAD 'hdfs://localhost:9000/pig_data/customers.txt' USING PigStorage(',');
orders = LOAD 'hdfs://localhost:9000/pig_data/orders.txt' USING PigStorage(',');
student = LOAD 'hdfs://localhost:9000/pig_data/student.txt' USING PigStorage(',');
set Command
set 命令用于显示/分配给 Pig 中使用的键的值。
Usage
使用这个命令,您可以将值设定到以下键中:
Key |
Description and values |
default_parallel |
您可以通过传递任意一个整数作为这个键的值,来设定 map 作业的 reducer 数。 |
debug |
您可以通过向此键传递 on/off 来关闭或打开 Pig 中的调试功能。 |
job.name |
您可以通过向此键传递一个字符串值来将作业名称设置为您需要的作业。 |
job.priority |
您可以通过向此键传递以下值之一来为作业设置作业优先级 - very_lowlownormalhighvery_high |
stream.skippath |
对于流式传输,您可以通过以字符串的形式将路径传递到此键,从而设置不会传输数据的路径。 |
quit Command
您可以使用此命令退出 Grunt shell。
Usage
如下所示退出 Grunt shell。
grunt> quit
现在,我们来看看您可以在 Grunt shell 中控制 Apache Pig 的命令。
exec Command
使用 exec 命令,我们可以从 Grunt shell 中执行 Pig 脚本。
Syntax
下面是 exec 的实用工具命令的语法。
grunt> exec [–param param_name = param_value] [–param_file file_name] [script]
Example
让我们假设 HDFS 的 /pig_data/ 目录中有一个名为 student.txt 的文件,其内容如下。
Student.txt
001,Rajiv,Hyderabad
002,siddarth,Kolkata
003,Rajesh,Delhi
而且,假设我们在 HDFS 的 /pig_data/ 目录中有一个名为 sample_script.pig 的脚本文件,其内容如下。
Sample_script.pig
student = LOAD 'hdfs://localhost:9000/pig_data/student.txt' USING PigStorage(',')
as (id:int,name:chararray,city:chararray);
Dump student;
现在,让我们使用 exec 命令从 Grunt shell 中执行上述脚本,如下所示。
grunt> exec /sample_script.pig
Output
exec 命令执行 sample_script.pig 中的脚本。就像脚本中指示的那样,它将 student.txt 文件加载到 Pig 中,并向您显示以下内容的 Dump 运算符结果。
(1,Rajiv,Hyderabad)
(2,siddarth,Kolkata)
(3,Rajesh,Delhi)
kill Command
您可以使用此命令从 Grunt shell 中终止作业。
Syntax
下面是 kill 命令的语法。
grunt> kill JobId
Example
假设有一个正在运行的 Pig 作业,其 ID 为 Id_0055 ,您可以使用 kill 命令从 Grunt shell 中将其终止,如下所示。
grunt> kill Id_0055
run Command
您可以使用 run 命令从 Grunt shell 中运行 Pig 脚本。
Syntax
以下给出了 run 命令的语法。
grunt> run [–param param_name = param_value] [–param_file file_name] script
Example
让我们假设 HDFS 的 /pig_data/ 目录中有一个名为 student.txt 的文件,其内容如下。
Student.txt
001,Rajiv,Hyderabad
002,siddarth,Kolkata
003,Rajesh,Delhi
而且,假设我们在本地文件系统中有一个名为 sample_script.pig 的脚本文件,其内容如下。
Sample_script.pig
student = LOAD 'hdfs://localhost:9000/pig_data/student.txt' USING
PigStorage(',') as (id:int,name:chararray,city:chararray);
现在,让我们使用运行命令如下所示从 Grunt shell 运行上面的脚本。
grunt> run /sample_script.pig
你可以使用 Dump operator 查看脚本的输出,如下所示。
grunt> Dump;
(1,Rajiv,Hyderabad)
(2,siddarth,Kolkata)
(3,Rajesh,Delhi)
Note − exec 和 run 命令之间的区别在于,如果我们使用 run ,脚本中的语句将在命令历史记录中可用。
Pig Latin – Basics
Pig Latin 是用于使用 Apache Pig 分析 Hadoop 中数据的语言。在本章中,我们将讨论 Pig Latin 的基础知识,例如 Pig Latin 语句、数据类型、常规运算符和关系运算符以及 Pig Latin UDF。
Pig Latin – Data Model
如同在前面的章节中所讨论的,Pig 的数据模式是完全嵌套的。 Relation 是 Pig Latin 数据模型的最外层结构。并且它是一个 bag ,其中:
-
一个 Bag 是元组的集合。
-
一个元组是有序字段集。
-
一个字段是一小段数据。
Pig Latin – Statemets
在使用 Pig Latin 处理数据时, statements 是基本结构。
-
这些语句使用 relations 。它们包含 expressions 和 schemas 。
-
每个语句以分号 (;) 结尾。
-
我们将通过语句使用 Pig Latin 提供的操作符执行各种操作。
-
除了 LOAD 和 STORE,在执行所有其他操作时,Pig Latin 语句将关系作为输入,并生成另一个关系作为输出。
-
只要你在 Grunt shell 中输入 Load 语句,就会对其执行语义检查。要查看模式的内容,你需要使用 Dump 操作符。只有在执行 dump 操作后,才会执行将数据加载到文件系统中的 MapReduce 作业。
Pig Latin – Data types
下表描述了 Pig Latin 数据类型。
S.N. |
Data Type |
Description & Example |
1 |
int |
表示带符号的 32 位整数。 Example : 8 |
2 |
long |
表示带符号的 64 位整数。 Example : 5L |
3 |
float |
表示带符号的 32 位浮点数。 Example : 5.5F |
4 |
double |
表示 64 位浮点数。 Example : 10.5 |
5 |
chararray |
表示 Unicode UTF-8 格式中的字符数组(字符串)。 Example : ‘tutorials point’ |
6 |
Bytearray |
表示字节数组(blob)。 |
7 |
Boolean |
表示布尔值。 Example : true/ false。 |
8 |
Datetime |
代表日期时间。 Example : 1970-01-01T00:00:00.000+00:00 |
9 |
Biginteger |
代表 Java BigInteger。 Example : 60708090709 |
10 |
Bigdecimal |
代表 Java BigDecimal Example : 185.98376256272893883 |
Complex Types |
11 |
Tuple |
元组是有序的字段集。 Example : (raja, 30) |
12 |
Bag |
集合是由元组构成的集合。 Example : {(raju,30),(Mohhammad,45)} |
13 |
Map |
Null Values
所有以上数据类型的值均可以为 NULL。Apache Pig 对 null 值的处理方式与 SQL 类似。
NULL 可以是未知值或不存在的值。它用作可选值中的占位符。这些 Null 可能自然发生或可以是某个操作的结果。
Pig Latin – Arithmetic Operators
下表描述了 Pig Latin 的算术运算符。假设 a = 10 且 b = 20。
Operator |
Description |
Example |
+ |
Addition − 加法运算符位于左右两侧。 |
a + b 将得到 30 |
− |
Subtraction − 减法运算符,运算符右边减去左边。 |
a-b 的结果为 -10 |
* |
Multiplication − 乘法运算符位于左右两侧。 |
a * b 将得到 200 |
/ |
Division − 除法运算符,运算符左边除以右边。 |
b / a 将得到 2 |
% |
Modulus − 除法运算符,运算符左边除以右边,取得余数。 |
b % a 将得到 0 |
? : |
Bincond − 布尔值运算符,如下所示有三个运算符。变量 x = (表达式)? value1 为 true 时: value2 为 false 时。 |
b = (a == 1)? 20: 30;如果 a=1,则 b 的值为 20。如果 a!=1,则 b 的值为 30。 |
CASE WHEN THEN ELSE END |
Case − case 运算符等同于嵌套的 bincond 运算符。 |
CASE f2 % 2WHEN 0 THEN 'even’WHEN 1 THEN 'odd’END |
Pig Latin – Comparison Operators
下表描述了 Pig Latin 的比较运算符。
Operator |
Description |
Example |
== |
Equal - 检查两个操作数的值是否相等;如果相等,则条件变为真。 |
(a = b) 为假 |
!= |
Not Equal - 检查两个操作数的值是否相等。如果值不相等,则条件变为真。 |
(a != b) 为 true。 |
> |
Greater than - 检查左操作数的值是否大于右操作数的值。如果大于,则条件变为真。 |
(a > b) 为 false。 |
< |
Less than - 检查左操作数的值是否小于右操作数的值。如果小于,则条件变为真。 |
(a < b) 为 true。 |
>= |
Greater than or equal to - 检查左操作数的值是否大于或等于右操作数的值。如果大于或等于,则条件变为真。 |
(a >= b) 为 false。 |
⇐ |
Less than or equal to - 检查左操作数的值是否小于或等于右操作数的值。如果小于或等于,则条件变为真。 |
(a ⇐ b) 为 true。 |
matches |
Pattern matching - 检查左手边的字符串是否与右手边的常量匹配。 |
f1 matches '.tutorial.' |
Pig Latin – Type Construction Operators
下表描述了 Pig Latin 的 Type 构造运算符。
Operator |
Description |
Example |
() |
Tuple constructor operator - 此运算符用于构造一个元组。 |
(Raju, 30) |
{} |
Bag constructor operator - 此运算符用于构造一个包。 |
{(Raju, 30), (Mohammad, 45)} |
[] |
Map constructor operator - 此运算符用于构造一个元组。 |
[name#Raja, age#30] |
Pig Latin – Relational Operations
下表描述了 Pig Latin 的关系运算符。
Operator |
Description |
Loading and Storing |
LOAD |
将数据从文件系统(本地/HDFS)加载到关系。 |
STORE |
将关系保存到文件系统(本地/HDFS)。 |
Filtering |
FILTER |
从关系中删除不需要的行。 |
DISTINCT |
从关系中删除重复的行。 |
FOREACH, GENERATE |
根据数据列生成数据转换。 |
STREAM |
使用外部程序转换关系。 |
Grouping and Joining |
JOIN |
连接两个或更多关系。 |
COGROUP |
对两个或更多关系中的数据进行分组。 |
GROUP |
对单个关系中的数据进行分组。 |
CROSS |
创建两个或更多关系的笛卡尔积。 |
Sorting |
ORDER |
根据一个或更多字段,按升序或降序对关系进行排序。 |
LIMIT |
从关系中获取有限数量的元组。 |
Combining and Splitting |
UNION |
将两个或更多关系合并到一个关系中。 |
SPLIT |
将一个关系拆分为两个或更多关系。 |
Diagnostic Operators |
DUMP |
在控制台上打印关系内容。 |
DESCRIBE |
描述关系的模式。 |
EXPLAIN |
查看用于计算关系的逻辑、物理或 MapReduce 执行计划。 |
ILLUSTRATE |
查看一系列语句的分步执行。 |
Apache Pig - Reading Data
一般来说,Apache Pig 在 Hadoop 的基础上运行。它是一种分析工具,可以分析存储在 *H*adoop *F*ile *S*ystem 中的大数据集。要使用 Apache Pig 分析数据,我们必须先将数据加载到 Apache Pig 中。本章将介绍如何从 HDFS 加载数据到 Apache Pig。
Preparing HDFS
在 MapReduce 模式下,Pig 从 HDFS 读取(加载)数据,并把结果存储回 HDFS。因此,让我们启动 HDFS,并创建以下示例数据:
Student ID |
First Name |
Last Name |
Phone |
City |
001 |
Rajiv |
Reddy |
9848022337 |
Hyderabad |
002 |
siddarth |
Battacharya |
9848022338 |
Kolkata |
003 |
Rajesh |
Khanna |
9848022339 |
Delhi |
004 |
Preethi |
Agarwal |
9848022330 |
Pune |
005 |
Trupthi |
Mohanthy |
9848022336 |
Bhuwaneshwar |
006 |
Archana |
Mishra |
9848022335 |
Chennai |
以上数据集包含六个学生的个人详细信息,如 ID、名字、姓氏、电话号码和城市。
Step 1: Verifying Hadoop
首先,使用 Hadoop 版本命令验证安装,如下所示。
$ hadoop version
如果您的系统包含 Hadoop,并且设置了 PATH 变量,那么您将获得以下输出:
Hadoop 2.6.0
Subversion https://git-wip-us.apache.org/repos/asf/hadoop.git -r
e3496499ecb8d220fba99dc5ed4c99c8f9e33bb1
Compiled by jenkins on 2014-11-13T21:10Z
Compiled with protoc 2.5.0
From source with checksum 18e43357c8f927c0695f1e9522859d6a
This command was run using /home/Hadoop/hadoop/share/hadoop/common/hadoop
common-2.6.0.jar
Step 2: Starting HDFS
浏览 Hadoop 的 sbin 目录,并启动 yarn 和 Hadoop dfs(分布式文件系统),如下所示。
cd /$Hadoop_Home/sbin/
$ start-dfs.sh
localhost: starting namenode, logging to /home/Hadoop/hadoop/logs/hadoopHadoop-namenode-localhost.localdomain.out
localhost: starting datanode, logging to /home/Hadoop/hadoop/logs/hadoopHadoop-datanode-localhost.localdomain.out
Starting secondary namenodes [0.0.0.0]
starting secondarynamenode, logging to /home/Hadoop/hadoop/logs/hadoop-Hadoopsecondarynamenode-localhost.localdomain.out
$ start-yarn.sh
starting yarn daemons
starting resourcemanager, logging to /home/Hadoop/hadoop/logs/yarn-Hadoopresourcemanager-localhost.localdomain.out
localhost: starting nodemanager, logging to /home/Hadoop/hadoop/logs/yarnHadoop-nodemanager-localhost.localdomain.out
Step 3: Create a Directory in HDFS
在 Hadoop DFS 中,您可以使用命令 mkdir 创建目录。在以下所需路径中使用名称 Pig_Data 在 HDFS 中创建一个新目录。
$cd /$Hadoop_Home/bin/
$ hdfs dfs -mkdir hdfs://localhost:9000/Pig_Data
Step 4: Placing the data in HDFS
Pig 的输入文件包含单独行中的每个元组/记录。并且记录的实体由分隔符分隔(在我们的示例中,我们使用了 “,” )。
在本地文件系统中,创建一个输入文件 student_data.txt ,其中包含以下数据。
001,Rajiv,Reddy,9848022337,Hyderabad
002,siddarth,Battacharya,9848022338,Kolkata
003,Rajesh,Khanna,9848022339,Delhi
004,Preethi,Agarwal,9848022330,Pune
005,Trupthi,Mohanthy,9848022336,Bhuwaneshwar
006,Archana,Mishra,9848022335,Chennai.
现在,使用 put 命令将文件从本地文件系统移动到 HDFS,如下所示。(您也可以使用 copyFromLocal 命令。)
$ cd $HADOOP_HOME/bin
$ hdfs dfs -put /home/Hadoop/Pig/Pig_Data/student_data.txt dfs://localhost:9000/pig_data/
Verifying the file
您可以使用 cat 命令验证文件是否已移入 HDFS,如下所示。
$ cd $HADOOP_HOME/bin
$ hdfs dfs -cat hdfs://localhost:9000/pig_data/student_data.txt
Output
您可以看到以下所示的文件内容。
15/10/01 12:16:55 WARN util.NativeCodeLoader: Unable to load native-hadoop
library for your platform... using builtin-java classes where applicable
001,Rajiv,Reddy,9848022337,Hyderabad
002,siddarth,Battacharya,9848022338,Kolkata
003,Rajesh,Khanna,9848022339,Delhi
004,Preethi,Agarwal,9848022330,Pune
005,Trupthi,Mohanthy,9848022336,Bhuwaneshwar
006,Archana,Mishra,9848022335,Chennai
The Load Operator
您可以使用 Pig Latin 的 LOAD 运算符从文件系统(HDFS/Local)加载数据到 Apache Pig 中。
Syntax
load 语句由 “=” 运算符分隔的两部分组成。在左侧,我们需要提及其关系的名称 where ,我们希望将数据存储到该名称中,并且在右侧,我们必须定义 how 我们存储数据的地方。以下是 Load 运算符的语法。
Relation_name = LOAD 'Input file path' USING function as schema;
其中,
-
relation_name − 我们必须提及其我们要存储数据的关联。
-
Input file path − 我们必须提及其文件存储所在的 HDFS 目录。(在 MapReduce 模式中)
-
function − 我们必须从 Apache Pig 提供的加载函数集中选择一个函数( BinStorage, JsonLoader, PigStorage, TextLoader )。
-
Schema − 我们必须定义数据的模式。我们可以按如下方式定义所需的模式:
(column1 : data type, column2 : data type, column3 : data type);
Note − 我们加载数据,而不指定模式。在这种情况下,列将被寻址为 $01、$02 等(检查)。
Start the Pig Grunt Shell
首先,打开 Linux 终端。以 MapReduce 模式启动 Pig Grunt shell,如下所示。
$ Pig –x mapreduce
它将启动 Pig Grunt shell,如下所示。
15/10/01 12:33:37 INFO pig.ExecTypeProvider: Trying ExecType : LOCAL
15/10/01 12:33:37 INFO pig.ExecTypeProvider: Trying ExecType : MAPREDUCE
15/10/01 12:33:37 INFO pig.ExecTypeProvider: Picked MAPREDUCE as the ExecType
2015-10-01 12:33:38,080 [main] INFO org.apache.pig.Main - Apache Pig version 0.15.0 (r1682971) compiled Jun 01 2015, 11:44:35
2015-10-01 12:33:38,080 [main] INFO org.apache.pig.Main - Logging error messages to: /home/Hadoop/pig_1443683018078.log
2015-10-01 12:33:38,242 [main] INFO org.apache.pig.impl.util.Utils - Default bootup file /home/Hadoop/.pigbootup not found
2015-10-01 12:33:39,630 [main]
INFO org.apache.pig.backend.hadoop.executionengine.HExecutionEngine - Connecting to hadoop file system at: hdfs://localhost:9000
grunt>
Execute the Load Statement
现在通过在 Grunt shell 中执行以下 Pig Latin 语句将 student_data.txt 文件中的数据加载到 Pig 中。
grunt> student = LOAD 'hdfs://localhost:9000/pig_data/student_data.txt'
USING PigStorage(',')
as ( id:int, firstname:chararray, lastname:chararray, phone:chararray,
city:chararray );
以下是上述语句的描述。
Relation name |
我们已将数据存储在 student 模式中。 |
Input file path |
我们正在从 HDFS 的 /pig_data/ 目录中的 student_data.txt, 文件中读取数据。 |
Storage function |
我们使用了 PigStorage() 函数。它将数据作为结构化文本文件加载并存储。它采用一个分隔符,用它分隔元组的每个实体,作为参数。默认情况下,它采用“\t”作为参数。 |
schema |
我们使用以下模式存储数据:columnidfirstnamelastnamephonecitydatatypeintchar arraychar arraychar arraychar array |
column |
id |
firstname |
lastname |
phone |
city |
datatype |
int |
char array |
char array |
char array |
char array |
Note − load 语句只会将数据加载到 Pig 中指定的关系中。要验证 Load 语句的执行,您必须使用将在下一章中讨论的 Diagnostic Operators 。
Apache Pig - Storing Data
在前面的章节中,我们学习了如何将数据加载到 Apache Pig 中。您可以使用 store 运算符,将加载的数据存储在文件系统中。本章解释了如何使用 Store 运算符将数据存储在 Apache Pig 中。
Example
假设我们在 HDFS 中有一个文件 student_data.txt ,内容如下。
001,Rajiv,Reddy,9848022337,Hyderabad
002,siddarth,Battacharya,9848022338,Kolkata
003,Rajesh,Khanna,9848022339,Delhi
004,Preethi,Agarwal,9848022330,Pune
005,Trupthi,Mohanthy,9848022336,Bhuwaneshwar
006,Archana,Mishra,9848022335,Chennai.
并且我们已使用 LOAD 运算符,将它读入到一个关系 student 中,如下所示。
grunt> student = LOAD 'hdfs://localhost:9000/pig_data/student_data.txt'
USING PigStorage(',')
as ( id:int, firstname:chararray, lastname:chararray, phone:chararray,
city:chararray );
现在,让我们将关系存储在 HDFS 目录 “/pig_Output/” 中,如下所示。
grunt> STORE student INTO ' hdfs://localhost:9000/pig_Output/ ' USING PigStorage (',');
Output
在执行 store 语句后,您将获得以下输出。将创建一个具有指定名称的目录,并将数据存储在其中。
2015-10-05 13:05:05,429 [main] INFO org.apache.pig.backend.hadoop.executionengine.mapReduceLayer.
MapReduceLau ncher - 100% complete
2015-10-05 13:05:05,429 [main] INFO org.apache.pig.tools.pigstats.mapreduce.SimplePigStats -
Script Statistics:
HadoopVersion PigVersion UserId StartedAt FinishedAt Features
2.6.0 0.15.0 Hadoop 2015-10-0 13:03:03 2015-10-05 13:05:05 UNKNOWN
Success!
Job Stats (time in seconds):
JobId Maps Reduces MaxMapTime MinMapTime AvgMapTime MedianMapTime
job_14459_06 1 0 n/a n/a n/a n/a
MaxReduceTime MinReduceTime AvgReduceTime MedianReducetime Alias Feature
0 0 0 0 student MAP_ONLY
OutPut folder
hdfs://localhost:9000/pig_Output/
Input(s): Successfully read 0 records from: "hdfs://localhost:9000/pig_data/student_data.txt"
Output(s): Successfully stored 0 records in: "hdfs://localhost:9000/pig_Output"
Counters:
Total records written : 0
Total bytes written : 0
Spillable Memory Manager spill count : 0
Total bags proactively spilled: 0
Total records proactively spilled: 0
Job DAG: job_1443519499159_0006
2015-10-05 13:06:06,192 [main] INFO org.apache.pig.backend.hadoop.executionengine
.mapReduceLayer.MapReduceLau ncher - Success!
Verification
您可以如下所示验证存储的数据。
Step 1
首先,使用 ls 命令列出 pig_output 目录中的文件,如下所示。
hdfs dfs -ls 'hdfs://localhost:9000/pig_Output/'
Found 2 items
rw-r--r- 1 Hadoop supergroup 0 2015-10-05 13:03 hdfs://localhost:9000/pig_Output/_SUCCESS
rw-r--r- 1 Hadoop supergroup 224 2015-10-05 13:03 hdfs://localhost:9000/pig_Output/part-m-00000
您可以看到,执行 store 语句后创建了两个文件。
Step 2
使用 cat 命令,列出 part-m-00000 文件的内容,如下所示。
$ hdfs dfs -cat 'hdfs://localhost:9000/pig_Output/part-m-00000'
1,Rajiv,Reddy,9848022337,Hyderabad
2,siddarth,Battacharya,9848022338,Kolkata
3,Rajesh,Khanna,9848022339,Delhi
4,Preethi,Agarwal,9848022330,Pune
5,Trupthi,Mohanthy,9848022336,Bhuwaneshwar
6,Archana,Mishra,9848022335,Chennai
Apache Pig - Diagnostic Operators
load 语句将简单地把数据加载到 Apache Pig 中指定的关系中。要验证 Load 语句的执行,你必须使用 Diagnostic Operators 。Pig Latin 提供四种不同的诊断操作符 −
-
Dump operator
-
Describe operator
-
Explanation operator
-
Illustration operator
在本章中,我们将讨论 Pig Latin 的 Dump 操作符。
Dump Operator
Dump 操作符用于运行 Pig Latin 语句并在屏幕上显示结果。它通常用于调试目的。
Example
假设我们在 HDFS 中有一个文件 student_data.txt ,内容如下。
001,Rajiv,Reddy,9848022337,Hyderabad
002,siddarth,Battacharya,9848022338,Kolkata
003,Rajesh,Khanna,9848022339,Delhi
004,Preethi,Agarwal,9848022330,Pune
005,Trupthi,Mohanthy,9848022336,Bhuwaneshwar
006,Archana,Mishra,9848022335,Chennai.
并且我们已使用 LOAD 运算符,将它读入到一个关系 student 中,如下所示。
grunt> student = LOAD 'hdfs://localhost:9000/pig_data/student_data.txt'
USING PigStorage(',')
as ( id:int, firstname:chararray, lastname:chararray, phone:chararray,
city:chararray );
现在,我们使用 Dump operator 打印关系的内容,如下所示。
grunt> Dump student
一旦执行了上述 Pig Latin 语句,它将启动 MapReduce 作业以从 HDFS 读取数据。它将生成以下输出。
2015-10-01 15:05:27,642 [main]
INFO org.apache.pig.backend.hadoop.executionengine.mapReduceLayer.MapReduceLauncher -
100% complete
2015-10-01 15:05:27,652 [main]
INFO org.apache.pig.tools.pigstats.mapreduce.SimplePigStats - Script Statistics:
HadoopVersion PigVersion UserId StartedAt FinishedAt Features
2.6.0 0.15.0 Hadoop 2015-10-01 15:03:11 2015-10-01 05:27 UNKNOWN
Success!
Job Stats (time in seconds):
JobId job_14459_0004
Maps 1
Reduces 0
MaxMapTime n/a
MinMapTime n/a
AvgMapTime n/a
MedianMapTime n/a
MaxReduceTime 0
MinReduceTime 0
AvgReduceTime 0
MedianReducetime 0
Alias student
Feature MAP_ONLY
Outputs hdfs://localhost:9000/tmp/temp580182027/tmp757878456,
Input(s): Successfully read 0 records from: "hdfs://localhost:9000/pig_data/
student_data.txt"
Output(s): Successfully stored 0 records in: "hdfs://localhost:9000/tmp/temp580182027/
tmp757878456"
Counters: Total records written : 0 Total bytes written : 0 Spillable Memory Manager
spill count : 0Total bags proactively spilled: 0 Total records proactively spilled: 0
Job DAG: job_1443519499159_0004
2015-10-01 15:06:28,403 [main]
INFO org.apache.pig.backend.hadoop.executionengine.mapReduceLayer.MapReduceLau ncher - Success!
2015-10-01 15:06:28,441 [main] INFO org.apache.pig.data.SchemaTupleBackend -
Key [pig.schematuple] was not set... will not generate code.
2015-10-01 15:06:28,485 [main]
INFO org.apache.hadoop.mapreduce.lib.input.FileInputFormat - Total input paths
to process : 1
2015-10-01 15:06:28,485 [main]
INFO org.apache.pig.backend.hadoop.executionengine.util.MapRedUtil - Total input paths
to process : 1
(1,Rajiv,Reddy,9848022337,Hyderabad)
(2,siddarth,Battacharya,9848022338,Kolkata)
(3,Rajesh,Khanna,9848022339,Delhi)
(4,Preethi,Agarwal,9848022330,Pune)
(5,Trupthi,Mohanthy,9848022336,Bhuwaneshwar)
(6,Archana,Mishra,9848022335,Chennai)
Apache Pig - Describe Operator
describe 运算符用于查看关系的模式。
Example
假设我们在 HDFS 中有一个文件 student_data.txt ,内容如下。
001,Rajiv,Reddy,9848022337,Hyderabad
002,siddarth,Battacharya,9848022338,Kolkata
003,Rajesh,Khanna,9848022339,Delhi
004,Preethi,Agarwal,9848022330,Pune
005,Trupthi,Mohanthy,9848022336,Bhuwaneshwar
006,Archana,Mishra,9848022335,Chennai.
并且我们已使用 LOAD 运算符,将它读入到一个关系 student 中,如下所示。
grunt> student = LOAD 'hdfs://localhost:9000/pig_data/student_data.txt' USING PigStorage(',')
as ( id:int, firstname:chararray, lastname:chararray, phone:chararray, city:chararray );
现在,让我们描述名为 student 的关系并验证模式,如下所示。
grunt> describe student;
Apache Pig - Explain Operator
explain 运算符用于显示关联的逻辑、物理和 MapReduce 执行计划。
Example
假设我们在 HDFS 中有一个文件 student_data.txt ,内容如下。
001,Rajiv,Reddy,9848022337,Hyderabad
002,siddarth,Battacharya,9848022338,Kolkata
003,Rajesh,Khanna,9848022339,Delhi
004,Preethi,Agarwal,9848022330,Pune
005,Trupthi,Mohanthy,9848022336,Bhuwaneshwar
006,Archana,Mishra,9848022335,Chennai.
并且我们已使用 LOAD 运算符,将它读入到一个关系 student 中,如下所示。
grunt> student = LOAD 'hdfs://localhost:9000/pig_data/student_data.txt' USING PigStorage(',')
as ( id:int, firstname:chararray, lastname:chararray, phone:chararray, city:chararray );
现在,让我们使用 explain 运算符,来解释名为 student 的关系,如下所示。
grunt> explain student;
Output
它将产生以下输出。
$ explain student;
2015-10-05 11:32:43,660 [main]
2015-10-05 11:32:43,660 [main] INFO org.apache.pig.newplan.logical.optimizer
.LogicalPlanOptimizer -
{RULES_ENABLED=[AddForEach, ColumnMapKeyPrune, ConstantCalculator,
GroupByConstParallelSetter, LimitOptimizer, LoadTypeCastInserter, MergeFilter,
MergeForEach, PartitionFilterOptimizer, PredicatePushdownOptimizer,
PushDownForEachFlatten, PushUpFilter, SplitFilter, StreamTypeCastInserter]}
#-----------------------------------------------
# New Logical Plan:
#-----------------------------------------------
student: (Name: LOStore Schema:
id#31:int,firstname#32:chararray,lastname#33:chararray,phone#34:chararray,city#
35:chararray)
|
|---student: (Name: LOForEach Schema:
id#31:int,firstname#32:chararray,lastname#33:chararray,phone#34:chararray,city#
35:chararray)
| |
| (Name: LOGenerate[false,false,false,false,false] Schema:
id#31:int,firstname#32:chararray,lastname#33:chararray,phone#34:chararray,city#
35:chararray)ColumnPrune:InputUids=[34, 35, 32, 33,
31]ColumnPrune:OutputUids=[34, 35, 32, 33, 31]
| | |
| | (Name: Cast Type: int Uid: 31)
| | | | | |---id:(Name: Project Type: bytearray Uid: 31 Input: 0 Column: (*))
| | |
| | (Name: Cast Type: chararray Uid: 32)
| | |
| | |---firstname:(Name: Project Type: bytearray Uid: 32 Input: 1
Column: (*))
| | |
| | (Name: Cast Type: chararray Uid: 33)
| | |
| | |---lastname:(Name: Project Type: bytearray Uid: 33 Input: 2
Column: (*))
| | |
| | (Name: Cast Type: chararray Uid: 34)
| | |
| | |---phone:(Name: Project Type: bytearray Uid: 34 Input: 3 Column:
(*))
| | |
| | (Name: Cast Type: chararray Uid: 35)
| | |
| | |---city:(Name: Project Type: bytearray Uid: 35 Input: 4 Column:
(*))
| |
| |---(Name: LOInnerLoad[0] Schema: id#31:bytearray)
| |
| |---(Name: LOInnerLoad[1] Schema: firstname#32:bytearray)
| |
| |---(Name: LOInnerLoad[2] Schema: lastname#33:bytearray)
| |
| |---(Name: LOInnerLoad[3] Schema: phone#34:bytearray)
| |
| |---(Name: LOInnerLoad[4] Schema: city#35:bytearray)
|
|---student: (Name: LOLoad Schema:
id#31:bytearray,firstname#32:bytearray,lastname#33:bytearray,phone#34:bytearray
,city#35:bytearray)RequiredFields:null
#-----------------------------------------------
# Physical Plan: #-----------------------------------------------
student: Store(fakefile:org.apache.pig.builtin.PigStorage) - scope-36
|
|---student: New For Each(false,false,false,false,false)[bag] - scope-35
| |
| Cast[int] - scope-21
| |
| |---Project[bytearray][0] - scope-20
| |
| Cast[chararray] - scope-24
| |
| |---Project[bytearray][1] - scope-23
| |
| Cast[chararray] - scope-27
| |
| |---Project[bytearray][2] - scope-26
| |
| Cast[chararray] - scope-30
| |
| |---Project[bytearray][3] - scope-29
| |
| Cast[chararray] - scope-33
| |
| |---Project[bytearray][4] - scope-32
|
|---student: Load(hdfs://localhost:9000/pig_data/student_data.txt:PigStorage(',')) - scope19
2015-10-05 11:32:43,682 [main]
INFO org.apache.pig.backend.hadoop.executionengine.mapReduceLayer.MRCompiler -
File concatenation threshold: 100 optimistic? false
2015-10-05 11:32:43,684 [main]
INFO org.apache.pig.backend.hadoop.executionengine.mapReduceLayer.MultiQueryOp timizer -
MR plan size before optimization: 1 2015-10-05 11:32:43,685 [main]
INFO org.apache.pig.backend.hadoop.executionengine.mapReduceLayer.
MultiQueryOp timizer - MR plan size after optimization: 1
#--------------------------------------------------
# Map Reduce Plan
#--------------------------------------------------
MapReduce node scope-37
Map Plan
student: Store(fakefile:org.apache.pig.builtin.PigStorage) - scope-36
|
|---student: New For Each(false,false,false,false,false)[bag] - scope-35
| |
| Cast[int] - scope-21
| |
| |---Project[bytearray][0] - scope-20
| |
| Cast[chararray] - scope-24
| |
| |---Project[bytearray][1] - scope-23
| |
| Cast[chararray] - scope-27
| |
| |---Project[bytearray][2] - scope-26
| |
| Cast[chararray] - scope-30
| |
| |---Project[bytearray][3] - scope-29
| |
| Cast[chararray] - scope-33
| |
| |---Project[bytearray][4] - scope-32
|
|---student:
Load(hdfs://localhost:9000/pig_data/student_data.txt:PigStorage(',')) - scope
19-------- Global sort: false
----------------
Apache Pig - Illustrate Operator
illustrate 运算符为您提供了一系列语句的分步执行。
Example
假设我们在 HDFS 中有一个文件 student_data.txt ,内容如下。
001,Rajiv,Reddy,9848022337,Hyderabad
002,siddarth,Battacharya,9848022338,Kolkata
003,Rajesh,Khanna,9848022339,Delhi
004,Preethi,Agarwal,9848022330,Pune
005,Trupthi,Mohanthy,9848022336,Bhuwaneshwar
006,Archana,Mishra,9848022335,Chennai.
并且我们已使用 LOAD 运算符,将它读入到一个关系 student 中,如下所示。
grunt> student = LOAD 'hdfs://localhost:9000/pig_data/student_data.txt' USING PigStorage(',')
as ( id:int, firstname:chararray, lastname:chararray, phone:chararray, city:chararray );
现在,让我们说明名为 student 的关系,如下所示。
grunt> illustrate student;
Output
在执行上面的语句后,您将得到以下输出。
grunt> illustrate student;
INFO org.apache.pig.backend.hadoop.executionengine.mapReduceLayer.PigMapOnly$M ap - Aliases
being processed per job phase (AliasName[line,offset]): M: student[1,10] C: R:
---------------------------------------------------------------------------------------------
|student | id:int | firstname:chararray | lastname:chararray | phone:chararray | city:chararray |
---------------------------------------------------------------------------------------------
| | 002 | siddarth | Battacharya | 9848022338 | Kolkata |
---------------------------------------------------------------------------------------------
Apache Pig - Group Operator
GROUP 运算符用于对一个或多个关系中的数据进行分组。它收集具有相同键的数据。
Example
假设我们有一个名为 student_details.txt 的文件位于 HDFS 目录 /pig_data/ 中,如下所示。
student_details.txt
001,Rajiv,Reddy,21,9848022337,Hyderabad
002,siddarth,Battacharya,22,9848022338,Kolkata
003,Rajesh,Khanna,22,9848022339,Delhi
004,Preethi,Agarwal,21,9848022330,Pune
005,Trupthi,Mohanthy,23,9848022336,Bhuwaneshwar
006,Archana,Mishra,23,9848022335,Chennai
007,Komal,Nayak,24,9848022334,trivendram
008,Bharathi,Nambiayar,24,9848022333,Chennai
我们将此文件加载到 Apache Pig 中,关系名称为 student_details ,如下所示。
grunt> student_details = LOAD 'hdfs://localhost:9000/pig_data/student_details.txt' USING PigStorage(',')
as (id:int, firstname:chararray, lastname:chararray, age:int, phone:chararray, city:chararray);
现在,让我们按年龄对关系中的记录/元组进行分组,如下所示。
grunt> group_data = GROUP student_details by age;
Output
然后,您将得到输出,显示关系 group_data 的内容,如下所示。在这里,您可以看到结果模式有两列−
-
一个是 age ,我们按它对关系进行分组。
-
另一个是 bag ,其中包含元组组、具有相应年龄的学生记录。
(21,{(4,Preethi,Agarwal,21,9848022330,Pune),(1,Rajiv,Reddy,21,9848022337,Hydera bad)})
(22,{(3,Rajesh,Khanna,22,9848022339,Delhi),(2,siddarth,Battacharya,22,984802233 8,Kolkata)})
(23,{(6,Archana,Mishra,23,9848022335,Chennai),(5,Trupthi,Mohanthy,23,9848022336 ,Bhuwaneshwar)})
(24,{(8,Bharathi,Nambiayar,24,9848022333,Chennai),(7,Komal,Nayak,24,9848022334, trivendram)})
您可以使用 describe 命令查看分组数据后的表模式,如下所示。
grunt> Describe group_data;
group_data: {group: int,student_details: {(id: int,firstname: chararray,
lastname: chararray,age: int,phone: chararray,city: chararray)}}
同样,您可以使用 illustrate 命令获取模式的示例说明,如下所示。
$ Illustrate group_data;
它将生成如下输出:
-------------------------------------------------------------------------------------------------
|group_data| group:int | student_details:bag{:tuple(id:int,firstname:chararray,lastname:chararray,age:int,phone:chararray,city:chararray)}|
-------------------------------------------------------------------------------------------------
| | 21 | { 4, Preethi, Agarwal, 21, 9848022330, Pune), (1, Rajiv, Reddy, 21, 9848022337, Hyderabad)}|
| | 2 | {(2,siddarth,Battacharya,22,9848022338,Kolkata),(003,Rajesh,Khanna,22,9848022339,Delhi)}|
-------------------------------------------------------------------------------------------------
Grouping by Multiple Columns
让我们按年龄和城市对关系进行分组,如下所示。
grunt> group_multiple = GROUP student_details by (age, city);
您可以使用 Dump 运算符验证关系 group_multiple 的内容,如下所示。
grunt> Dump group_multiple;
((21,Pune),{(4,Preethi,Agarwal,21,9848022330,Pune)})
((21,Hyderabad),{(1,Rajiv,Reddy,21,9848022337,Hyderabad)})
((22,Delhi),{(3,Rajesh,Khanna,22,9848022339,Delhi)})
((22,Kolkata),{(2,siddarth,Battacharya,22,9848022338,Kolkata)})
((23,Chennai),{(6,Archana,Mishra,23,9848022335,Chennai)})
((23,Bhuwaneshwar),{(5,Trupthi,Mohanthy,23,9848022336,Bhuwaneshwar)})
((24,Chennai),{(8,Bharathi,Nambiayar,24,9848022333,Chennai)})
(24,trivendram),{(7,Komal,Nayak,24,9848022334,trivendram)})
Group All
您可以按所有列对关系进行分组,如下所示。
grunt> group_all = GROUP student_details All;
现在,验证关系 group_all 的内容,如下所示。
grunt> Dump group_all;
(all,{(8,Bharathi,Nambiayar,24,9848022333,Chennai),(7,Komal,Nayak,24,9848022334 ,trivendram),
(6,Archana,Mishra,23,9848022335,Chennai),(5,Trupthi,Mohanthy,23,9848022336,Bhuw aneshwar),
(4,Preethi,Agarwal,21,9848022330,Pune),(3,Rajesh,Khanna,22,9848022339,Delhi),
(2,siddarth,Battacharya,22,9848022338,Kolkata),(1,Rajiv,Reddy,21,9848022337,Hyd erabad)})
Apache Pig - Cogroup Operator
COGROUP 运算符或多或少与 GROUP 运算符以相同的方式工作。这两个运算符之间的唯一区别是, group 运算符通常用于一个关系,而 cogroup 运算符用于涉及两个或更多关系的语句。
Grouping Two Relations using Cogroup
假设我们在 HDFS 目录 /pig_data/ 中有两个文件,名称分别是 student_details.txt 和 employee_details.txt ,如下所示。
student_details.txt
001,Rajiv,Reddy,21,9848022337,Hyderabad
002,siddarth,Battacharya,22,9848022338,Kolkata
003,Rajesh,Khanna,22,9848022339,Delhi
004,Preethi,Agarwal,21,9848022330,Pune
005,Trupthi,Mohanthy,23,9848022336,Bhuwaneshwar
006,Archana,Mishra,23,9848022335,Chennai
007,Komal,Nayak,24,9848022334,trivendram
008,Bharathi,Nambiayar,24,9848022333,Chennai
employee_details.txt
001,Robin,22,newyork
002,BOB,23,Kolkata
003,Maya,23,Tokyo
004,Sara,25,London
005,David,23,Bhuwaneshwar
006,Maggy,22,Chennai
并且我们已将这些文件加载到 Pig 中,关系名称分别是 student_details 和 employee_details ,如下所示。
grunt> student_details = LOAD 'hdfs://localhost:9000/pig_data/student_details.txt' USING PigStorage(',')
as (id:int, firstname:chararray, lastname:chararray, age:int, phone:chararray, city:chararray);
grunt> employee_details = LOAD 'hdfs://localhost:9000/pig_data/employee_details.txt' USING PigStorage(',')
as (id:int, name:chararray, age:int, city:chararray);
现在,让我们使用键值 age 对关系 student_details 和 employee_details 的记录/元组进行分组,如下所示。
grunt> cogroup_data = COGROUP student_details by age, employee_details by age;
Output
它将产生以下输出,显示关系 cogroup_data 的内容,如下所示。
(21,{(4,Preethi,Agarwal,21,9848022330,Pune), (1,Rajiv,Reddy,21,9848022337,Hyderabad)},
{ })
(22,{ (3,Rajesh,Khanna,22,9848022339,Delhi), (2,siddarth,Battacharya,22,9848022338,Kolkata) },
{ (6,Maggy,22,Chennai),(1,Robin,22,newyork) })
(23,{(6,Archana,Mishra,23,9848022335,Chennai),(5,Trupthi,Mohanthy,23,9848022336 ,Bhuwaneshwar)},
{(5,David,23,Bhuwaneshwar),(3,Maya,23,Tokyo),(2,BOB,23,Kolkata)})
(24,{(8,Bharathi,Nambiayar,24,9848022333,Chennai),(7,Komal,Nayak,24,9848022334, trivendram)},
{ })
(25,{ },
{(4,Sara,25,London)})
cogroup 运算符根据年龄对每个关系的元组进行分组,其中每个组表示一个特定的年龄值。
例如,如果我们考虑结果的第 1 个元组,则它按年龄 21 分组。它包含两个包 −
-
第一个包保存了来自第一个关系(本例中为 student_details )具有年龄 21 的所有元组,
-
第二个包包含来自第二个关系(本例中为 employee_details )具有年龄 21 的所有元组。
如果关系没有元组具有年龄值 21,它将返回一个空包。
Apache Pig - Join Operator
JOIN 运算符用于组合来自两个或更多关系的记录。在执行连接操作时,我们从每个关系中声明一个(或一组)元组作为键。当这些键匹配时,这两个特定的元组将被匹配,否则记录将被丢弃。连接可以是以下类型 −
-
Self-join
-
Inner-join
-
外连接 - 左连接、右连接和全连接
本章使用示例说明如何在 Pig Latin 中使用连接运算符。假设我们在 HDFS 的 /pig_data/ 目录中有两个文件,名为 customers.txt 和 orders.txt ,如下所示。
customers.txt
1,Ramesh,32,Ahmedabad,2000.00
2,Khilan,25,Delhi,1500.00
3,kaushik,23,Kota,2000.00
4,Chaitali,25,Mumbai,6500.00
5,Hardik,27,Bhopal,8500.00
6,Komal,22,MP,4500.00
7,Muffy,24,Indore,10000.00
orders.txt
102,2009-10-08 00:00:00,3,3000
100,2009-10-08 00:00:00,3,1500
101,2009-11-20 00:00:00,2,1560
103,2008-05-20 00:00:00,4,2060
我们用关系 customers 和 orders 将这两个文件加载到 Pig 中,如下所示。
grunt> customers = LOAD 'hdfs://localhost:9000/pig_data/customers.txt' USING PigStorage(',')
as (id:int, name:chararray, age:int, address:chararray, salary:int);
grunt> orders = LOAD 'hdfs://localhost:9000/pig_data/orders.txt' USING PigStorage(',')
as (oid:int, date:chararray, customer_id:int, amount:int);
现在让我们对这两个关系执行各种 Join 操作。
Self - join
Self-join 用于像表一样将表与自身连接起来,暂时重新命名至少一个关系。
通常,在 Apache Pig 中,为了执行自连接,我们会使用不同的别名(名称)多次加载相同的数据。因此,让我们像下面所示将文件 customers.txt 的内容加载为两个表。
grunt> customers1 = LOAD 'hdfs://localhost:9000/pig_data/customers.txt' USING PigStorage(',')
as (id:int, name:chararray, age:int, address:chararray, salary:int);
grunt> customers2 = LOAD 'hdfs://localhost:9000/pig_data/customers.txt' USING PigStorage(',')
as (id:int, name:chararray, age:int, address:chararray, salary:int);
Syntax
下面是使用 JOIN 操作符执行 self-join 操作的语法。
grunt> Relation3_name = JOIN Relation1_name BY key, Relation2_name BY key ;
Example
让我们对关系 customers 执行 self-join 操作,方法是像下面所示连接两个关系 customers1 和 customers2 。
grunt> customers3 = JOIN customers1 BY id, customers2 BY id;
Output
它将生成以下输出,显示关系 customers 的内容。
(1,Ramesh,32,Ahmedabad,2000,1,Ramesh,32,Ahmedabad,2000)
(2,Khilan,25,Delhi,1500,2,Khilan,25,Delhi,1500)
(3,kaushik,23,Kota,2000,3,kaushik,23,Kota,2000)
(4,Chaitali,25,Mumbai,6500,4,Chaitali,25,Mumbai,6500)
(5,Hardik,27,Bhopal,8500,5,Hardik,27,Bhopal,8500)
(6,Komal,22,MP,4500,6,Komal,22,MP,4500)
(7,Muffy,24,Indore,10000,7,Muffy,24,Indore,10000)
Inner Join
Inner Join 使用非常频繁;它也称为 equijoin 。当在两个表中匹配时,内连接返回行。
它根据连接谓词通过组合两个关系(比如 A 和 B)的列值创建新关系。该查询将 A 的每一行与 B 的每一行进行比较,以查找满足连接谓词的所有行对。当满足连接谓词时,将 A 和 B 的每一对匹配行的列值组合成结果行。
Syntax
以下是使用 JOIN 操作符执行 inner join 操作的语法。
grunt> result = JOIN relation1 BY columnname, relation2 BY columnname;
Example
让我们对两个关系 customers 和 orders 执行 inner join 操作,如下所示。
grunt> coustomer_orders = JOIN customers BY id, orders BY customer_id;
Output
你将得到以下输出,即名为 coustomer_orders 的关系的内容。
(2,Khilan,25,Delhi,1500,101,2009-11-20 00:00:00,2,1560)
(3,kaushik,23,Kota,2000,100,2009-10-08 00:00:00,3,1500)
(3,kaushik,23,Kota,2000,102,2009-10-08 00:00:00,3,3000)
(4,Chaitali,25,Mumbai,6500,103,2008-05-20 00:00:00,4,2060)
Note −
外连接:不同于内连接, outer join 从至少一个关系中返回所有行。外连接操作以三种方式进行 −
-
Left outer join
-
Right outer join
-
Full outer join
Left Outer Join
如果右关系中没有匹配, left outer Join 操作也会返回左表中的所有行。
Syntax
以下是使用 JOIN 操作符执行 left outer join 操作的语法。
grunt> Relation3_name = JOIN Relation1_name BY id LEFT OUTER, Relation2_name BY customer_id;
Example
让我们对关系 customers 和 orders 执行左外连接操作,如下所示。
grunt> outer_left = JOIN customers BY id LEFT OUTER, orders BY customer_id;
Output
它将产生以下输出,显示关系 outer_left 的内容。
(1,Ramesh,32,Ahmedabad,2000,,,,)
(2,Khilan,25,Delhi,1500,101,2009-11-20 00:00:00,2,1560)
(3,kaushik,23,Kota,2000,100,2009-10-08 00:00:00,3,1500)
(3,kaushik,23,Kota,2000,102,2009-10-08 00:00:00,3,3000)
(4,Chaitali,25,Mumbai,6500,103,2008-05-20 00:00:00,4,2060)
(5,Hardik,27,Bhopal,8500,,,,)
(6,Komal,22,MP,4500,,,,)
(7,Muffy,24,Indore,10000,,,,)
Right Outer Join
right outer join 操作会返回右侧表的全部行,即使在左侧表中没有匹配项也是如此。
Syntax
以下是使用 JOIN 运算符执行 right outer join 操作的语法。
grunt> outer_right = JOIN customers BY id RIGHT, orders BY customer_id;
Full Outer Join
full outer join 操作会在某个关系中出现匹配项时返回行。
Syntax
以下是使用 JOIN 运算符执行 full outer join 的语法。
grunt> outer_full = JOIN customers BY id FULL OUTER, orders BY customer_id;
Example
让我们对两个关系 customers 和 orders 执行 full outer join 操作,如下所示。
grunt> outer_full = JOIN customers BY id FULL OUTER, orders BY customer_id;
Output
它将产生以下输出,显示关系 outer_full 的内容。
(1,Ramesh,32,Ahmedabad,2000,,,,)
(2,Khilan,25,Delhi,1500,101,2009-11-20 00:00:00,2,1560)
(3,kaushik,23,Kota,2000,100,2009-10-08 00:00:00,3,1500)
(3,kaushik,23,Kota,2000,102,2009-10-08 00:00:00,3,3000)
(4,Chaitali,25,Mumbai,6500,103,2008-05-20 00:00:00,4,2060)
(5,Hardik,27,Bhopal,8500,,,,)
(6,Komal,22,MP,4500,,,,)
(7,Muffy,24,Indore,10000,,,,)
Using Multiple Keys
我们可以使用多个键执行 JOIN 操作。
Syntax
以下是使用多个键对两张表执行 JOIN 操作的方法。
grunt> Relation3_name = JOIN Relation2_name BY (key1, key2), Relation3_name BY (key1, key2);
假设我们在 HDFS 的 /pig_data/ 目录中拥有两个文件,即 employee.txt 和 employee_contact.txt ,如下所示。
employee.txt
001,Rajiv,Reddy,21,programmer,003
002,siddarth,Battacharya,22,programmer,003
003,Rajesh,Khanna,22,programmer,003
004,Preethi,Agarwal,21,programmer,003
005,Trupthi,Mohanthy,23,programmer,003
006,Archana,Mishra,23,programmer,003
007,Komal,Nayak,24,teamlead,002
008,Bharathi,Nambiayar,24,manager,001
employee_contact.txt
001,9848022337,Rajiv@gmail.com,Hyderabad,003
002,9848022338,siddarth@gmail.com,Kolkata,003
003,9848022339,Rajesh@gmail.com,Delhi,003
004,9848022330,Preethi@gmail.com,Pune,003
005,9848022336,Trupthi@gmail.com,Bhuwaneshwar,003
006,9848022335,Archana@gmail.com,Chennai,003
007,9848022334,Komal@gmail.com,trivendram,002
008,9848022333,Bharathi@gmail.com,Chennai,001
并且我们已使用关系 employee 和 employee_contact 将这两个文件加载到 Pig 中,如下所示。
grunt> employee = LOAD 'hdfs://localhost:9000/pig_data/employee.txt' USING PigStorage(',')
as (id:int, firstname:chararray, lastname:chararray, age:int, designation:chararray, jobid:int);
grunt> employee_contact = LOAD 'hdfs://localhost:9000/pig_data/employee_contact.txt' USING PigStorage(',')
as (id:int, phone:chararray, email:chararray, city:chararray, jobid:int);
现在,让我们使用 JOIN 运算符连接这两个关系的内容,如下所示。
grunt> emp = JOIN employee BY (id,jobid), employee_contact BY (id,jobid);
Output
它将生成以下输出,显示如下所示的命名为 emp 的关联中的内容。
(1,Rajiv,Reddy,21,programmer,113,1,9848022337,Rajiv@gmail.com,Hyderabad,113)
(2,siddarth,Battacharya,22,programmer,113,2,9848022338,siddarth@gmail.com,Kolka ta,113)
(3,Rajesh,Khanna,22,programmer,113,3,9848022339,Rajesh@gmail.com,Delhi,113)
(4,Preethi,Agarwal,21,programmer,113,4,9848022330,Preethi@gmail.com,Pune,113)
(5,Trupthi,Mohanthy,23,programmer,113,5,9848022336,Trupthi@gmail.com,Bhuwaneshw ar,113)
(6,Archana,Mishra,23,programmer,113,6,9848022335,Archana@gmail.com,Chennai,113)
(7,Komal,Nayak,24,teamlead,112,7,9848022334,Komal@gmail.com,trivendram,112)
(8,Bharathi,Nambiayar,24,manager,111,8,9848022333,Bharathi@gmail.com,Chennai,111)
Apache Pig - Cross Operator
CROSS 运算符计算两个或更多关系的笛卡尔积。本章以示例说明如何在 Pig Latin 中使用 cross 运算符。
Example
假设我们在 HDFS 的 /pig_data/ 目录中具有两个文件 customers.txt 和 orders.txt ,如下所示。
customers.txt
1,Ramesh,32,Ahmedabad,2000.00
2,Khilan,25,Delhi,1500.00
3,kaushik,23,Kota,2000.00
4,Chaitali,25,Mumbai,6500.00
5,Hardik,27,Bhopal,8500.00
6,Komal,22,MP,4500.00
7,Muffy,24,Indore,10000.00
orders.txt
102,2009-10-08 00:00:00,3,3000
100,2009-10-08 00:00:00,3,1500
101,2009-11-20 00:00:00,2,1560
103,2008-05-20 00:00:00,4,2060
我们用关系 customers 和 orders 将这两个文件加载到 Pig 中,如下所示。
grunt> customers = LOAD 'hdfs://localhost:9000/pig_data/customers.txt' USING PigStorage(',')
as (id:int, name:chararray, age:int, address:chararray, salary:int);
grunt> orders = LOAD 'hdfs://localhost:9000/pig_data/orders.txt' USING PigStorage(',')
as (oid:int, date:chararray, customer_id:int, amount:int);
现在,让我们使用 cross 运算符对这两个关系执行笛卡尔积,如下所示。
grunt> cross_data = CROSS customers, orders;
Output
它将产生以下输出,显示关系 cross_data 的内容。
(7,Muffy,24,Indore,10000,103,2008-05-20 00:00:00,4,2060)
(7,Muffy,24,Indore,10000,101,2009-11-20 00:00:00,2,1560)
(7,Muffy,24,Indore,10000,100,2009-10-08 00:00:00,3,1500)
(7,Muffy,24,Indore,10000,102,2009-10-08 00:00:00,3,3000)
(6,Komal,22,MP,4500,103,2008-05-20 00:00:00,4,2060)
(6,Komal,22,MP,4500,101,2009-11-20 00:00:00,2,1560)
(6,Komal,22,MP,4500,100,2009-10-08 00:00:00,3,1500)
(6,Komal,22,MP,4500,102,2009-10-08 00:00:00,3,3000)
(5,Hardik,27,Bhopal,8500,103,2008-05-20 00:00:00,4,2060)
(5,Hardik,27,Bhopal,8500,101,2009-11-20 00:00:00,2,1560)
(5,Hardik,27,Bhopal,8500,100,2009-10-08 00:00:00,3,1500)
(5,Hardik,27,Bhopal,8500,102,2009-10-08 00:00:00,3,3000)
(4,Chaitali,25,Mumbai,6500,103,2008-05-20 00:00:00,4,2060)
(4,Chaitali,25,Mumbai,6500,101,2009-20 00:00:00,4,2060)
(2,Khilan,25,Delhi,1500,101,2009-11-20 00:00:00,2,1560)
(2,Khilan,25,Delhi,1500,100,2009-10-08 00:00:00,3,1500)
(2,Khilan,25,Delhi,1500,102,2009-10-08 00:00:00,3,3000)
(1,Ramesh,32,Ahmedabad,2000,103,2008-05-20 00:00:00,4,2060)
(1,Ramesh,32,Ahmedabad,2000,101,2009-11-20 00:00:00,2,1560)
(1,Ramesh,32,Ahmedabad,2000,100,2009-10-08 00:00:00,3,1500)
(1,Ramesh,32,Ahmedabad,2000,102,2009-10-08 00:00:00,3,3000)-11-20 00:00:00,2,1560)
(4,Chaitali,25,Mumbai,6500,100,2009-10-08 00:00:00,3,1500)
(4,Chaitali,25,Mumbai,6500,102,2009-10-08 00:00:00,3,3000)
(3,kaushik,23,Kota,2000,103,2008-05-20 00:00:00,4,2060)
(3,kaushik,23,Kota,2000,101,2009-11-20 00:00:00,2,1560)
(3,kaushik,23,Kota,2000,100,2009-10-08 00:00:00,3,1500)
(3,kaushik,23,Kota,2000,102,2009-10-08 00:00:00,3,3000)
(2,Khilan,25,Delhi,1500,103,2008-05-20 00:00:00,4,2060)
(2,Khilan,25,Delhi,1500,101,2009-11-20 00:00:00,2,1560)
(2,Khilan,25,Delhi,1500,100,2009-10-08 00:00:00,3,1500)
(2,Khilan,25,Delhi,1500,102,2009-10-08 00:00:00,3,3000)
(1,Ramesh,32,Ahmedabad,2000,103,2008-05-20 00:00:00,4,2060)
(1,Ramesh,32,Ahmedabad,2000,101,2009-11-20 00:00:00,2,1560)
(1,Ramesh,32,Ahmedabad,2000,100,2009-10-08 00:00:00,3,1500)
(1,Ramesh,32,Ahmedabad,2000,102,2009-10-08 00:00:00,3,3000)
Apache Pig - Union Operator
Pig Latin 的 UNION 运算符用于合并两个关系的内容。要在两个关系上执行 UNION 操作,它们的列和域必须相同。
Example
假设我们在 HDFS 的 /pig_data/ 目录中具有两个文件 student_data1.txt 和 student_data2.txt ,如下所示。
Student_data1.txt
001,Rajiv,Reddy,9848022337,Hyderabad
002,siddarth,Battacharya,9848022338,Kolkata
003,Rajesh,Khanna,9848022339,Delhi
004,Preethi,Agarwal,9848022330,Pune
005,Trupthi,Mohanthy,9848022336,Bhuwaneshwar
006,Archana,Mishra,9848022335,Chennai.
Student_data2.txt
7,Komal,Nayak,9848022334,trivendram.
8,Bharathi,Nambiayar,9848022333,Chennai.
我们已使用关系 student1 和 student2 将这两个文件加载到 Pig 中,如下所示。
grunt> student1 = LOAD 'hdfs://localhost:9000/pig_data/student_data1.txt' USING PigStorage(',')
as (id:int, firstname:chararray, lastname:chararray, phone:chararray, city:chararray);
grunt> student2 = LOAD 'hdfs://localhost:9000/pig_data/student_data2.txt' USING PigStorage(',')
as (id:int, firstname:chararray, lastname:chararray, phone:chararray, city:chararray);
现在,让我们使用 UNION 运算符合并这两个关系的内容,如下所示。
grunt> student = UNION student1, student2;
Output
它将显示以下输出,显示关系 student 的内容。
(1,Rajiv,Reddy,9848022337,Hyderabad) (2,siddarth,Battacharya,9848022338,Kolkata)
(3,Rajesh,Khanna,9848022339,Delhi)
(4,Preethi,Agarwal,9848022330,Pune)
(5,Trupthi,Mohanthy,9848022336,Bhuwaneshwar)
(6,Archana,Mishra,9848022335,Chennai)
(7,Komal,Nayak,9848022334,trivendram)
(8,Bharathi,Nambiayar,9848022333,Chennai)
Apache Pig - Split Operator
SPLIT 运算符用于将一个关系拆分为两个或更多个关系。
Syntax
以下是 SPLIT 运算符的语法。
grunt> SPLIT Relation1_name INTO Relation2_name IF (condition1), Relation2_name (condition2),
Example
假设我们有一个名为 student_details.txt 的文件位于 HDFS 目录 /pig_data/ 中,如下所示。
student_details.txt
001,Rajiv,Reddy,21,9848022337,Hyderabad
002,siddarth,Battacharya,22,9848022338,Kolkata
003,Rajesh,Khanna,22,9848022339,Delhi
004,Preethi,Agarwal,21,9848022330,Pune
005,Trupthi,Mohanthy,23,9848022336,Bhuwaneshwar
006,Archana,Mishra,23,9848022335,Chennai
007,Komal,Nayak,24,9848022334,trivendram
008,Bharathi,Nambiayar,24,9848022333,Chennai
我们已经将此文件载入 Pig,并将其关系名称命名为 student_details ,如下所示。
student_details = LOAD 'hdfs://localhost:9000/pig_data/student_details.txt' USING PigStorage(',')
as (id:int, firstname:chararray, lastname:chararray, age:int, phone:chararray, city:chararray);
现在,让我们将该关系分成两部分,一部分列出年龄小于 23 岁的员工,另一部分列出年龄在 22 到 25 之间的员工。
SPLIT student_details into student_details1 if age<23, student_details2 if (22<age and age>25);
Verification
使用 DUMP 运算符验证关系 student_details1 和 student_details2 ,如下所示。
grunt> Dump student_details1;
grunt> Dump student_details2;
Output
它将生成以下输出,分别显示关系 student_details1 和 student_details2 的内容。
grunt> Dump student_details1;
(1,Rajiv,Reddy,21,9848022337,Hyderabad)
(2,siddarth,Battacharya,22,9848022338,Kolkata)
(3,Rajesh,Khanna,22,9848022339,Delhi)
(4,Preethi,Agarwal,21,9848022330,Pune)
grunt> Dump student_details2;
(5,Trupthi,Mohanthy,23,9848022336,Bhuwaneshwar)
(6,Archana,Mishra,23,9848022335,Chennai)
(7,Komal,Nayak,24,9848022334,trivendram)
(8,Bharathi,Nambiayar,24,9848022333,Chennai)
Apache Pig - Filter Operator
FILTER 运算符用于根据条件从关系中选择所需的元组。
Example
假设我们有一个名为 student_details.txt 的文件位于 HDFS 目录 /pig_data/ 中,如下所示。
student_details.txt
001,Rajiv,Reddy,21,9848022337,Hyderabad
002,siddarth,Battacharya,22,9848022338,Kolkata
003,Rajesh,Khanna,22,9848022339,Delhi
004,Preethi,Agarwal,21,9848022330,Pune
005,Trupthi,Mohanthy,23,9848022336,Bhuwaneshwar
006,Archana,Mishra,23,9848022335,Chennai
007,Komal,Nayak,24,9848022334,trivendram
008,Bharathi,Nambiayar,24,9848022333,Chennai
我们已经将此文件载入 Pig,并将其关系名称命名为 student_details ,如下所示。
grunt> student_details = LOAD 'hdfs://localhost:9000/pig_data/student_details.txt' USING PigStorage(',')
as (id:int, firstname:chararray, lastname:chararray, age:int, phone:chararray, city:chararray);
现在,让我们使用 Filter 运算符获取属于金奈市的学生的详细信息。
filter_data = FILTER student_details BY city == 'Chennai';
Apache Pig - Distinct Operator
DISTINCT 运算符用于从关系中删除冗余(重复)元组。
Example
假设我们有一个名为 student_details.txt 的文件位于 HDFS 目录 /pig_data/ 中,如下所示。
student_details.txt
001,Rajiv,Reddy,9848022337,Hyderabad
002,siddarth,Battacharya,9848022338,Kolkata
002,siddarth,Battacharya,9848022338,Kolkata
003,Rajesh,Khanna,9848022339,Delhi
003,Rajesh,Khanna,9848022339,Delhi
004,Preethi,Agarwal,9848022330,Pune
005,Trupthi,Mohanthy,9848022336,Bhuwaneshwar
006,Archana,Mishra,9848022335,Chennai
006,Archana,Mishra,9848022335,Chennai
我们已经将此文件载入 Pig,并将其关系名称命名为 student_details ,如下所示。
grunt> student_details = LOAD 'hdfs://localhost:9000/pig_data/student_details.txt' USING PigStorage(',')
as (id:int, firstname:chararray, lastname:chararray, phone:chararray, city:chararray);
现在,让我们使用 DISTINCT 运算符从名为 student_details 的关系中删除冗余(重复)的元组,并将其存储为另一个名为 distinct_data 的关系,如下所示。
grunt> distinct_data = DISTINCT student_details;
Apache Pig - Foreach Operator
FOREACH 运算符用于基于列数据生成指定的数据转换。
Example
假设我们有一个名为 student_details.txt 的文件位于 HDFS 目录 /pig_data/ 中,如下所示。
student_details.txt
001,Rajiv,Reddy,21,9848022337,Hyderabad
002,siddarth,Battacharya,22,9848022338,Kolkata
003,Rajesh,Khanna,22,9848022339,Delhi
004,Preethi,Agarwal,21,9848022330,Pune
005,Trupthi,Mohanthy,23,9848022336,Bhuwaneshwar
006,Archana,Mishra,23,9848022335,Chennai
007,Komal,Nayak,24,9848022334,trivendram
008,Bharathi,Nambiayar,24,9848022333,Chennai
我们已经将此文件载入 Pig,并将其关系名称命名为 student_details ,如下所示。
grunt> student_details = LOAD 'hdfs://localhost:9000/pig_data/student_details.txt' USING PigStorage(',')
as (id:int, firstname:chararray, lastname:chararray,age:int, phone:chararray, city:chararray);
让我们现在从关系 student_details 中获取每个学生的 id、age 和 city 值,并使用 foreach 运算符将其存储到另一个名为 foreach_data 的关系中,如下所示。
grunt> foreach_data = FOREACH student_details GENERATE id,age,city;
Apache Pig - Order By
ORDER BY 运算符用于按一个或多个字段对关系中的内容以排序方式显示。
Example
假设我们有一个名为 student_details.txt 的文件位于 HDFS 目录 /pig_data/ 中,如下所示。
student_details.txt
001,Rajiv,Reddy,21,9848022337,Hyderabad
002,siddarth,Battacharya,22,9848022338,Kolkata
003,Rajesh,Khanna,22,9848022339,Delhi
004,Preethi,Agarwal,21,9848022330,Pune
005,Trupthi,Mohanthy,23,9848022336,Bhuwaneshwar
006,Archana,Mishra,23,9848022335,Chennai
007,Komal,Nayak,24,9848022334,trivendram
008,Bharathi,Nambiayar,24,9848022333,Chennai
我们已经将此文件载入 Pig,并将其关系名称命名为 student_details ,如下所示。
grunt> student_details = LOAD 'hdfs://localhost:9000/pig_data/student_details.txt' USING PigStorage(',')
as (id:int, firstname:chararray, lastname:chararray,age:int, phone:chararray, city:chararray);
现在,让我们按学生的年龄以降序对关系进行排序,并使用 ORDER BY 运算符将结果存储到另一个名为 order_by_data 的关系中,如下所示。
grunt> order_by_data = ORDER student_details BY age DESC;
Output
它将生成以下输出,显示关系 order_by_data 的内容。
(8,Bharathi,Nambiayar,24,9848022333,Chennai)
(7,Komal,Nayak,24,9848022334,trivendram)
(6,Archana,Mishra,23,9848022335,Chennai)
(5,Trupthi,Mohanthy,23,9848022336,Bhuwaneshwar)
(3,Rajesh,Khanna,22,9848022339,Delhi)
(2,siddarth,Battacharya,22,9848022338,Kolkata)
(4,Preethi,Agarwal,21,9848022330,Pune)
(1,Rajiv,Reddy,21,9848022337,Hyderabad)
Apache Pig - Limit Operator
LIMIT 运算符用于从关系中获取有限数量的元组。
Example
假设我们有一个名为 student_details.txt 的文件位于 HDFS 目录 /pig_data/ 中,如下所示。
student_details.txt
001,Rajiv,Reddy,21,9848022337,Hyderabad
002,siddarth,Battacharya,22,9848022338,Kolkata
003,Rajesh,Khanna,22,9848022339,Delhi
004,Preethi,Agarwal,21,9848022330,Pune
005,Trupthi,Mohanthy,23,9848022336,Bhuwaneshwar
006,Archana,Mishra,23,9848022335,Chennai
007,Komal,Nayak,24,9848022334,trivendram
008,Bharathi,Nambiayar,24,9848022333,Chennai
我们已经将此文件载入 Pig,并将其关系名称命名为 student_details ,如下所示。
grunt> student_details = LOAD 'hdfs://localhost:9000/pig_data/student_details.txt' USING PigStorage(',')
as (id:int, firstname:chararray, lastname:chararray,age:int, phone:chararray, city:chararray);
现在,让我们根据学生的年龄对关系进行降序排序,并将其存储到另一个名为 limit_data 的关系中,使用 ORDER BY 运算符,如下所示。
grunt> limit_data = LIMIT student_details 4;
Apache Pig - Eval Functions
Apache Pig 提供了各种内置函数,即 eval, load, store, math, string, bag 和 tuple 函数。
Eval Functions
以下是 Apache Pig 提供的 eval 函数列表。
S.N. |
Function & Description |
1 |
AVG() 计算包内数值的平均值。 |
2 |
BagToString() 将包中的元素连接成一个字符串。在连接时,我们可以在这些值之间放置一个分隔符(可选)。 |
3 |
CONCAT() 连接相同类型的两个或多个表达式。 |
4 |
COUNT() 获得包中元素的数量,同时计算包中元组的数量。 |
5 |
COUNT_STAR() 它类似于 COUNT() 函数。它用于获得包中元素的数量。 |
6 |
DIFF() 比较元组中的两个包(字段)。 |
7 |
IsEmpty() 检查包或映射是否为空。 |
8 |
MAX() 计算单列包中一列(数值或 chararray)的最高值。 |
9 |
MIN() 获得单列包中某一列的最小(最低)值(数值或字符数组)。 |
10 |
PluckTuple() 使用 Pig Latin PluckTuple() 函数,我们可以定义一个字符串前缀并筛选一个关系中以给定前缀开头的列。 |
11 |
SIZE() 根据任何 Pig 数据类型计算元素数量。 |
12 |
SUBTRACT() 减去两个包。它把两个包作为输入,并返回一个包,其中包含不在第二个包中的第一个包的元组。 |
13 |
SUM() 获得单列包中某一列的数值总和。 |
14 |
TOKENIZE() 将字符串(包含一组单词)分割成单独的元组中,并返回一个包含分割操作输出的包。 |
Apache Pig - Load & Store Functions
Apache Pig 中的 Load 和 Store 函数用于确定数据如何流入 Pig 并从 Pig 流出。这些函数与加载和存储运算符一起使用。以下是 Pig 中可用的加载和存储函数的列表。
S.N. |
Function & Description |
1 |
PigStorage() 加载和存储结构化文件。 |
2 |
TextLoader() 将非结构化数据加载到 Pig 中。 |
3 |
BinStorage() 使用机器可读格式将数据加载并存储到 Pig 中。 |
4 |
Handling Compression 在 Pig Latin 中,我们可以加载和存储压缩数据。 |
Apache Pig - String Functions
我们在 Apache Pig 中有以下字符串函数。
S.N. |
Functions & Description |
1 |
ENDSWITH(string, testAgainst) 要验证给定字符串是否以特定子字符串结尾。 |
2 |
STARTSWITH(string, substring) 接受两个字符串参数,并验证第一个字符串是否以第二个字符串开头。 |
3 |
SUBSTRING(string, startIndex, stopIndex) 从给定字符串中返回子字符串。 |
4 |
EqualsIgnoreCase(string1, string2) 比较两个字符串时忽略大小写。 |
5 |
INDEXOF(string, ‘character’, startIndex) 从开始索引向前搜索,返回字符在字符串中的第一次出现。 |
6 |
LAST_INDEX_OF(expression) 从开始索引向后搜索,返回字符在字符串中的最后一次出现。 |
7 |
LCFIRST(expression) 将字符串中的第一个字符转换为小写。 |
8 |
UCFIRST(expression) 返回将第一个字符转换为大写的字符串。 |
9 |
UPPER(expression) UPPER(expression) 返回转换为大写的字符串。 |
10 |
LOWER(expression) 将字符串中的所有字符转换为小写。 |
11 |
REPLACE(string, ‘oldChar’, ‘newChar’); 用新字符替换字符串中现有的字符。 |
12 |
STRSPLIT(string, regex, limit) 按给定的正则表达式的匹配项分割字符串。 |
13 |
STRSPLITTOBAG(string, regex, limit) 类似于 STRSPLIT() 函数,它按给定的分隔符分割字符串,并将结果返回到包中。 |
14 |
TRIM(expression) 返回删除前后面白的字符串副本。 |
15 |
LTRIM(expression) 返回删除前导空格的字符串副本。 |
16 |
RTRIM(expression) 返回删除结束空格的字符串副本。 |
Apache Pig - Date-time Functions
Apache Pig 提供以下日期和时间函数 −
S.N. |
Functions & Description |
1 |
ToDate(milliseconds) 此函数根据给定的参数返回一个日期时间对象。此函数的另一种变体是 ToDate(iosstring)、ToDate(userstring, format)、ToDate(userstring, format, timezone) |
2 |
CurrentTime() 返回当前时间的日期时间对象。 |
3 |
GetDay(datetime) 从日期时间对象返回一个月的日期。 |
4 |
GetHour(datetime) 从日期时间对象返回一天中的小时。 |
5 |
GetMilliSecond(datetime) 从日期时间对象返回一秒中的毫秒。 |
6 |
GetMinute(datetime) 从日期时间对象返回一小时中的分钟。 |
7 |
GetMonth(datetime) 从日期时间对象返回一年的月份。 |
8 |
GetSecond(datetime) 从日期时间对象返回一分钟的秒。 |
9 |
GetWeek(datetime) 从日期时间对象返回一年的周。 |
10 |
GetWeekYear(datetime) 从日期时间对象返回星期年。 |
11 |
GetYear(datetime) 从日期时间对象返回年。 |
12 |
AddDuration(datetime, duration) 返回日期时间对象和持续时间对象的结果。 |
13 |
SubtractDuration(datetime, duration) 减去 Date-Time 对象的 Duration 对象并返回结果。 |
14 |
DaysBetween(datetime1, datetime2) 返回两个日期时间对象之间的天数。 |
15 |
HoursBetween(datetime1, datetime2) 返回两个日期时间对象之间的小时数。 |
16 |
MilliSecondsBetween(datetime1, datetime2) 返回两个日期时间对象之间的时间间隔。 |
17 |
MinutesBetween(datetime1, datetime2) 返回两个日期时间对象之间的分钟数。 |
18 |
MonthsBetween(datetime1, datetime2) 返回两个日期时间对象之间的月数。 |
19 |
SecondsBetween(datetime1, datetime2) 返回两个日期时间对象之间的秒数。 |
20 |
WeeksBetween(datetime1, datetime2) 返回两个日期时间对象之间的周数。 |
21 |
YearsBetween(datetime1, datetime2) 返回两个日期时间对象之间的年数。 |
Apache Pig - Math Functions
我们在 Apache Pig 中有以下数学函数 −
S.N. |
Functions & Description |
1 |
ABS(expression) 获取表达式的绝对值。 |
2 |
ACOS(expression) 获取表达式的反余弦。 |
3 |
ASIN(expression) 获取表达式的反正弦。 |
4 |
ATAN(expression) 此函数用于获取表达式的反正切。 |
5 |
CBRT(expression) 此函数用于获取表达式的立方根。 |
6 |
CEIL(expression) 此函数用于获取四舍五入到最接近整数的表达式值。 |
7 |
COS(expression) 此函数用于获取表达式的三角余弦值。 |
8 |
COSH(expression) 此函数用于获取表达式的双曲余弦值。 |
9 |
EXP(expression) 此函数用于获取欧拉数 e 乘以 x 的幂的值。 |
10 |
FLOOR(expression) 获取向下舍入到最近的整数的表达式的值。 |
11 |
LOG(expression) 获取表达式的自然对数(以 e 为底)。 |
12 |
LOG10(expression) 获取表达式的以 10 为底的对数。 |
13 |
RANDOM( ) 获取一个大于或等于 0.0 且小于 1.0 的伪随机数字(类型 double)。 |
14 |
ROUND(expression) 获取舍入为整数(如果结果类型是浮点数)或舍入为长整数(如果结果类型是 double)的表达式的值。 |
15 |
SIN(expression) 获取表达式的正弦。 |
16 |
SINH(expression) 获取表达式的双曲正弦。 |
17 |
SQRT(expression) 获取表达式的正平方根。 |
18 |
TAN(expression) 获取角度的三角正切。 |
19 |
TANH(expression) 获取表达式的双曲正切。 |
Apache Pig - User Defined Functions
除了内置函数,Apache Pig 还广泛支持*U*ser *D*efined *F*unctions (UDF)。使用这些 UDF,我们可以定义自己的函数并使用它们。UDF 支持使用六种编程语言提供,分别是 Java、Jython、Python、JavaScript、Ruby 和 Groovy。
对于编写 UDF,Java 提供了完整支持,而所有其他语言都提供有限的支持。使用 Java,您可以编写涉及处理所有部分的 UDF,如数据加载/存储、列转换和聚合。由于 Apache Pig 是用 Java 编写的,因此使用 Java 语言编写的 UDF 与其他语言相比运行效率更高。
在 Apache Pig 中,我们还有一个名为 Piggybank 的 UDF Java 存储库。使用 Piggybank,我们可以访问其他用户编写的 Java UDF,并贡献自己的 UDF。
Types of UDF’s in Java
在使用 Java 编写 UDF 时,我们可以创建和使用以下三種類型的函数−
-
Filter Functions - 过滤器函数用作过滤器语句中的条件。这些函数接受 Pig 值作为输入并返回布尔值。
-
Eval Functions - Eval 函数用于 FOREACH-GENERATE 语句中。这些函数接受 Pig 值作为输入并返回 Pig 结果。
-
Algebraic Functions - 代数函数对 FOREACHGENERATE 语句中的内部包起作用。这些函数用于对内部包执行完整的 MapReduce 操作。
Writing UDF’s using Java
要使用 Java 编写 UDF,我们必须集成 Jar 文件 Pig-0.15.0.jar 。在本节中,我们将讨论如何使用 Eclipse 编写示例 UDF。在继续操作之前,请确保已在您的系统中安装了 Eclipse 和 Maven。
按照以下给出的步骤编写 UDF 函数:
-
打开 Eclipse 并创建一个新项目(比如 myproject )。
-
将新创建的项目转换为 Maven 项目。
-
将以下内容复制到 pom.xml 中。此文件包含 Apache Pig 和 Hadoop 核心 Jar 文件的 Maven 依赖项。
<project xmlns = "http://maven.apache.org/POM/4.0.0"
xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation = "http://maven.apache.org/POM/4.0.0http://maven.apache .org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>Pig_Udf</groupId>
<artifactId>Pig_Udf</artifactId>
<version>0.0.1-SNAPSHOT</version>
<build>
<sourceDirectory>src</sourceDirectory>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.3</version>
<configuration>
<source>1.7</source>
<target>1.7</target>
</configuration>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>org.apache.pig</groupId>
<artifactId>pig</artifactId>
<version>0.15.0</version>
</dependency>
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-core</artifactId>
<version>0.20.2</version>
</dependency>
</dependencies>
</project>
-
保存该文件并刷新它。您可以在 Maven Dependencies 部分中找到下载的 Jar 文件。
-
使用名称 Sample_Eval 创建一个新类文件,并复制以下内容。
import java.io.IOException;
import org.apache.pig.EvalFunc;
import org.apache.pig.data.Tuple;
import java.io.IOException;
import org.apache.pig.EvalFunc;
import org.apache.pig.data.Tuple;
public class Sample_Eval extends EvalFunc<String>{
public String exec(Tuple input) throws IOException {
if (input == null || input.size() == 0)
return null;
String str = (String)input.get(0);
return str.toUpperCase();
}
}
在编写 UDF 时,必须继承 EvalFunc 类并向 exec() 函数提供实现。在此函数内编写 UDF 所需的代码。在上述示例中,我们返回代码以将给定列的内容转换为大写。
-
在成功编译该类后,右键单击 Sample_Eval.java 文件。它将为您提供一个菜单。选择 export ,如下图所示。
-
单击 export 后,您将获得以下窗口。单击 JAR file 。
-
通过单击 Next> 按钮继续操作。您将获得另一个窗口,您需要在其中输入本地文件系统中的路径来存储 Jar 文件。
-
最后,单击 Finish 按钮。在指定的文件夹中,将创建 Jar 文件 sample_udf.jar 。此 Jar 文件包含用 Java 编写的 UDF。
Using the UDF
在编写 UDF 并生成 Jar 文件后,按照以下给出的步骤操作:
Step 1: Registering the Jar file
在编写 UDF(Java 中)后,我们必须使用 Register 运算符注册包含 UDF 的 Jar 文件。通过注册 Jar 文件,用户可以告知 Apache Pig UDF 的位置。
Syntax
以下是 Register 运算符的语法。
REGISTER path;
Example
作为一个示例,让我们在此章节的前面注册创建的 sample_udf.jar。
在本地模式下启动 Apache Pig 并注册 Jar 文件 sample_udf.jar,如下所示。
$cd PIG_HOME/bin
$./pig –x local
REGISTER '/$PIG_HOME/sample_udf.jar'
Note - 假设路径中为 /$PIG_HOME/sample_udf.jar
Step 2: Defining Alias
在注册 UDF 后,我们可以使用 Define 运算符为其定义别名。
Syntax
下文是 Define 运算符的语法。
DEFINE alias {function | [`command` [input] [output] [ship] [cache] [stderr] ] };
Example
如下所示定义 sample_eval 的别名。
DEFINE sample_eval sample_eval();
Step 3: Using the UDF
定义别名之后,您可以像使用内置函数一样使用 UDF。假设 HDFS /Pig_Data/ 目录中有个名为 emp_data 的文件,其中包含以下内容。
001,Robin,22,newyork
002,BOB,23,Kolkata
003,Maya,23,Tokyo
004,Sara,25,London
005,David,23,Bhuwaneshwar
006,Maggy,22,Chennai
007,Robert,22,newyork
008,Syam,23,Kolkata
009,Mary,25,Tokyo
010,Saran,25,London
011,Stacy,25,Bhuwaneshwar
012,Kelly,22,Chennai
假设我们像下面这样将这个文件载入 Pig。
grunt> emp_data = LOAD 'hdfs://localhost:9000/pig_data/emp1.txt' USING PigStorage(',')
as (id:int, name:chararray, age:int, city:chararray);
现在让我们使用 UDF sample_eval 将员工姓名转换为大写。
grunt> Upper_case = FOREACH emp_data GENERATE sample_eval(name);
如下所示,验证关联 Upper_case 的内容。
grunt> Dump Upper_case;
(ROBIN)
(BOB)
(MAYA)
(SARA)
(DAVID)
(MAGGY)
(ROBERT)
(SYAM)
(MARY)
(SARAN)
(STACY)
(KELLY)
Apache Pig - Running Scripts
在本章中,我们将了解如何在批处理模式下运行 Apache Pig 脚本。
Comments in Pig Script
在文件中编写脚本时,我们可以按照如下所示的方式在其中包含注释。
Executing Pig Script in Batch mode
在批处理模式下执行 Apache Pig 语句时,请按照以下步骤操作。
Step 2
执行 Apache Pig 脚本。你可以按照如下所示的方式从 shell(Linux)执行 Pig 脚本。
Local mode |
MapReduce mode |
$ pig -x local Sample_script.pig |
$ pig -x mapreduce Sample_script.pig |
你也可以按照如下所示的方式使用 exec 命令从 Grunt shell 执行它。
grunt> exec /sample_script.pig
Executing a Pig Script from HDFS
我们还可以执行驻留在 HDFS 中的 Pig 脚本。假设在名为 /pig_data/ 的 HDFS 目录中有一个名为 Sample_script.pig 的 Pig 脚本。我们可以按照如下所示的方式执行它。
$ pig -x mapreduce hdfs://localhost:9000/pig_data/Sample_script.pig
Example
假设我们在 HDFS 中有一个文件 student_details.txt ,内容如下。
student_details.txt
001,Rajiv,Reddy,21,9848022337,Hyderabad
002,siddarth,Battacharya,22,9848022338,Kolkata
003,Rajesh,Khanna,22,9848022339,Delhi
004,Preethi,Agarwal,21,9848022330,Pune
005,Trupthi,Mohanthy,23,9848022336,Bhuwaneshwar
006,Archana,Mishra,23,9848022335,Chennai
007,Komal,Nayak,24,9848022334,trivendram
008,Bharathi,Nambiayar,24,9848022333,Chennai
我们还有同一个 HDFS 目录中的一个样例脚本,名为 sample_script.pig 。该文件包含对 student 关系执行操作和转换的语句,如下所示。
student = LOAD 'hdfs://localhost:9000/pig_data/student_details.txt' USING PigStorage(',')
as (id:int, firstname:chararray, lastname:chararray, phone:chararray, city:chararray);
student_order = ORDER student BY age DESC;
student_limit = LIMIT student_order 4;
Dump student_limit;
-
该脚本的第一条语句将以 student_details.txt 命名的文件中数据载入到名为 student 的关系中。
-
该脚本的第二条语句将按照年龄对该关系的元组进行降序排列,并将其存储为 student_order 。
-
该脚本的第三个语句将把 student_order 中的前 4 个元组存储为 student_limit 。
-
最后,第四个语句将转储 student_limit 关系的内容。
现在让我们按照如下所示执行 sample_script.pig 。
$./pig -x mapreduce hdfs://localhost:9000/pig_data/sample_script.pig
Apache Pig 已经执行,并给出了内容如下。
(7,Komal,Nayak,24,9848022334,trivendram)
(8,Bharathi,Nambiayar,24,9848022333,Chennai)
(5,Trupthi,Mohanthy,23,9848022336,Bhuwaneshwar)
(6,Archana,Mishra,23,9848022335,Chennai)
2015-10-19 10:31:27,446 [main] INFO org.apache.pig.Main - Pig script completed in 12
minutes, 32 seconds and 751 milliseconds (752751 ms)