Apache Pig - 用户定义的函数

除了内置函数之外,Apache Pig还为 U ser D 定义的 F 组(UDF)提供了广泛的支持.使用这些UDF,我们可以定义自己的函数并使用它们. UDF支持以六种编程语言提供,即Java,Jython,Python,JavaScript,Ruby和Groovy.

为了编写UDF,Java提供了完整的支持,并提供了有限的支持在所有其余语言中.使用Java,您可以编写涉及数据加载/存储,列转换和聚合等处理的所有部分的UDF.由于Apache Pig是用Java编写的,因此与其他语言相比,使用Java语言编写的UDF工作效率很高.

在Apache Pig中,我们还有一个用于UDF的Java存储库,名为 Piggybank 的.使用Piggybank,我们可以访问其他用户编写的Java UDF,并贡献我们自己的UDF.

Java中的UDF类型

使用UDF编写时Java,我们可以创建和使用以下三种类型的函数 :

  • 过滤函数 &减去;过滤器函数用作过滤器语句中的条件.这些函数接受Pig值作为输入并返回布尔值.

  • Eval Functions :  Eval函数用于FOREACH-GENERATE语句.这些函数接受Pig值作为输入并返回Pig结果.

  • 代数函数 : 代数函数在FOREACHGENERATE语句中作用于内袋.这些函数用于在内袋上执行完整的MapReduce操作.

使用Java编写UDF

要使用Java编写UDF,我们必须集成jar文件 Pig-0.15.0.jar .在本节中,我们将讨论如何使用Eclipse编写示例UDF.在继续之前,请确保已在系统中安装了Eclipse和Maven.

按照下面给出的步骤编写UDF函数 :

  • 打开Eclipse并创建一个新项目(比如 myproject ).

  • 将新创建的项目转换为Maven项目.

  • 将以下内容复制到pom.xml中.此文件包含Apache Pig和Hadoop-core 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依赖项部分,您可以找到下载的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文件.它给你一个菜单.选择导出,如以下屏幕截图所示.

选择导出

  • 点击导出,您将看到以下窗口.点击 JAR文件.

点击导出

  • 点击下一步> 按钮继续进一步操作.您将获得另一个窗口,您需要在本地文件系统中输入路径,您需要存储jar文件.

jar export

  • 最后点击完成按钮.在指定的文件夹中,创建了一个Jar文件 sample_udf.jar .这个jar文件包含用Java编写的UDF.

使用UDF

写完之后UDF并生成Jar文件,按照下面给出的步骤&减去;

步骤1:注册Jar文件

编写UDF后(用Java编写)我们必须使用Register运算符注册包含UDF的Jar文件.通过注册Jar文件,用户可以将UDF的位置告知Apache Pig.

语法

如下所示是Register运算符的语法.

REGISTER path;

示例

作为示例,让我们注册之前创建的sample_udf.jar本章.

以本地模式启动Apache Pig并注册jar文件sample_udf.jar,如下所示.

$cd PIG_HOME/bin 
$./pig –x local 

REGISTER '/$PIG_HOME/sample_udf.jar'

注意 : 假设路径中的Jar文件 : /$PIG_HOME/sample_udf.jar

第2步:定义别名

注册UDF后,我们可以使用为其定义别名定义运算符.

语法

以下是Define运算符的语法.

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

示例

定义sample_eval的别名,如下所示.

DEFINE sample_eval sample_eval();

步骤3:使用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

并假设我们已加载此文件如下所示进入猪.

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)