Pig 用户定义的函数



  • 用户定义的函数

    除了内置的函数,Apache Pig提供了广泛的支持USER defined Functions(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的类型

    使用Java编写UDF时,我们可以创建和使用以下三种类型的函数-
    • 过滤器函数-过滤器函数用作过滤器语句中的条件。这些函数接受Pig值作为输入并返回布尔值。
    • 求值函数-求值函数用于FOREACH-GENERATE语句中。这些函数接受Pig值作为输入,并返回Pig结果。
    • 代数函数-代数函数在FOREACHGENERATE语句中作用于bag。这些函数用于对bag执行完整的MapReduce操作。
  • 使用Java编写UDF

    要使用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依赖关系”部分中,您可以找到下载的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文件。它为您提供菜单。选择导出,如以下屏幕截图所示。
    • pig
    • 点击export,您将获得以下窗口。单击JAR文件。
    • pig
    • 单击下一步>继续操作。您将看到另一个窗口,需要在其中输入本地文件系统中的路径,并在其中存储jar文件。
    • pig
    • 最后单击完成按钮。在指定的文件夹中,创建一个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运算符的语法。
    
    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
    
    
    并假定我们已将此文件加载到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)