前面已经介绍过Pig是在Hadoop的MapReduce上构建的一种类似SQL的脚本语言。Pig语言比使用Java、C++等语言编写大规模数据处理程序的难度要小N倍,实现同样效果的代码量也少N倍。Pig可以和Java/C/Shell语言互相配合,生成自定义函数(UDF),所以Pig虽是一种脚本语言,又具有Java/C/Shell等语言的优势。
Pig语言在本质上就是一种可以直接使用的SQL语言。我们在使用SQL语言的时候,需要将数据库变为SQLite等形式的数据库,用C等语言来调用或者进入SQLite等中再使用SQL,而Pig语言可以直接对文本进行操作,所以尽管它在本质上是一种SQL,但是却可以在文本上操作,所以非常利于处理文本等海量数据。
关于Pig最好的参考资料就是Pig的官方参考手册,网址为http://pig.apache.org/docs。
Pig语言中的关系(relation)、包(bag)、元组(tuple)、字段(field)、数据(data)的特点:
一个关系(relation)是一个包(bag),更具体地说,是一个外部的包(outer bag)。
一个包(bag)是一个元组(tuple)的集合。在Pig中,当表示数据时,用大括号{}括起来的东西表示一个包——无论是在教程中的实例演示,还是在Pig交互模式下的输出,都遵循这样的约定,请牢记这一点,因为不理解的话就会对数据结构的掌握产生偏差。
一个元组(tuple)是若干字段(field)的一个有序集(ordered set)。在Pig中,当表示数据时,用小括号()括起来的东西表示一个元组。
一个字段是一块数据(data)。
可以把“元组”想象成关系型数据库表中的一行,它含有一个或多个字段,其中,每一个字段可以是任何数据类型,并且可以有或者没有数据。
“关系”可以比喻成关系型数据库的一张表。在关系型数据库中,同一张表中的每一行都有固定的字段数,Pig中的“关系”与“元组”之间是否也是这样的情况呢?不是的。“关系”并不要求每一个“元组”都含有相同数量的字段,并且也不会要求各“元组”中在相同位置处的字段具有相同的数据类型。
Pig中可以嵌套使用Shell进行辅助处理,下面就以一个实际的例子来说明。
假设我们在某一步Pig处理后,得到类似下面b.txt中的数据:
\[root@localhost pig\]$ cat b.txt
1 5 98 = 7
34 8 6 3 2
62 0 6 = 65
问题:如何将数据中第4列中的“=”符号全部替换为9999?
Pig代码及输出结果如下:
grunt> A = LOAD 'b.txt' AS (col1:int, col2:int, col3:int, col4:chararray, col5:int); grunt> B = STREAM A THROUGH 'awk'{if($4 == "=") print $1"\t"$2"\t"$3"\t9999\t"$5; else print $0}"; grunt> DUMP B; (1,5,98,9999,7) (34,8,6,3,2) (62,0,6,9999,65)
我们来看看这段代码是如何做到的:
第一句代码:加载数据。
第二句代码:通过“STREAM…THROUGH…”的方式,我们可以调用一个Shell语句,用该Shell语句对A的每一行数据进行处理。此处的Shell逻辑为:当某一行数据的第4列为“=”符号时,将其替换为“9999”,否则就照原样输出。
第三句代码:输出B。