Pig用户定义函数


除了内置的功能,Apache的pig提供了广泛的支持 ü 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中,我们还为UDF的名为 Piggybank 的Java存储库。使用Piggybank,我们可以访问由其他用户编写的Java UDF,并贡献我们自己的UDF。

Java中的UDF类型

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

  • 过滤器功能 - 过滤器功能用作过滤器语句中的条件。 这些函数接受一个Pig值作为输入并返回一个布尔值。

  • 评估函数 - 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核心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文件。它给你一个菜单。选择 导出 ,如下面的截图所示。

选择导出

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

点击导出

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

罐出口

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

使用UDF

在编写UDF并生成Jar文件之后,请按照以下步骤进行操作 -

第1步:注册Jar文件

在编写UDF(使用Java)之后,我们必须使用注册运算符注册包含UDF的Jar文件。通过注册Jar文件,用户可以将UDF的位置提供给Apache Pig。

句法

以下给出的是注册运算符的语法。

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)