Pig 的 UDF 中存在 "in" 会导致问题
Presence of "in" in Pig's UDF causes problems
我在 pig 中尝试我的第一个 UDF 并编写了以下函数 -
package com.pig.in.action.assignments.udf;
import org.apache.pig.EvalFunc;
import org.apache.pig.PigWarning;
import org.apache.pig.data.Tuple;
import java.io.IOException;
public class CountLength extends EvalFunc<Integer> {
public Integer exec(Tuple inputVal) throws IOException {
// Validate Input Value ...
if (inputVal == null ||
inputVal.size() == 0 ||
inputVal.get(0) == null) {
// Emit warning text for user, and skip this iteration
super.warn("Inappropriate parameter, Skipping ...",
PigWarning.SKIP_UDF_CALL_FOR_NULL);
return null;
}
// Count # of characters in this string ...
final String inputString = (String) inputVal.get(0);
return inputString.length();
}
}
但是,当我尝试按如下方式使用它时,Pig 会抛出一条错误消息,至少在我的 UDF 上下文中它不容易理解:
grunt> cat dept.txt;
10,ACCOUNTING,NEW YORK
20,RESEARCH,DALLAS
30,SALES,CHICAGO
40,OPERATIONS,BOSTON
grunt> dept = LOAD '/user/sgn/dept.txt' USING PigStorage(',') AS (dept_no: INT, d_name: CHARARRAY, d_loc: CHARARRAY);
grunt> d = FOREACH dept GENERATE dept_no, com.pig.in.action.assignments.udf.CountLength(d_name);
2015-06-02 16:24:13,416 [main] ERROR org.apache.pig.tools.grunt.Grunt - ERROR 1200: <line 2, column 79> mismatched input '(' expecting SEMI_COLON
Details at logfile: /home/sgn/pig_1433261973141.log
谁能帮我弄清楚这是怎么回事?
我已经阅读了文档,但在我看来上面的示例中没有明显的错误。我在这里遗漏了什么吗?
这些是我在 pom.xml 中使用的库:
<dependency>
<groupId>org.apache.pig</groupId>
<artifactId>pig</artifactId>
<version>0.14.0</version>
</dependency>
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-core</artifactId>
<version>1.2.1</version>
</dependency>
是否存在兼容性问题?
谢谢,
-Vipul Pathak;
试过上面的例子。只要使用 REGISTER 命令注册了 jar 并且 jar 在 classpath 中可用,我们就不会看到任何错误。
REGISTER myudfs.jar;
dept = LOAD 'a.csv' USING PigStorage(',') AS (dept_no: INT, d_name: CHARARRAY, d_loc: CHARARRAY);
d = FOREACH dept GENERATE dept_no, CountLength(d_name) as length;
输入:a.csv
10,ACCOUNTING,NEW YORK
20,RESEARCH,DALLAS
30,SALES,CHICAGO
40,OPERATIONS,BOSTON
输出:d
(10,10)
(20,8)
(30,5)
(40,10)
N.B。 : 在上面 运行 中 class CountLength 已经在默认包中定义。
如果此 class - CountLength 已在包中定义 com.pig.utility 那么要访问 UDF,我们必须有如下的 DEFINE 语句
DEFINE CountLength com.pig.utility.CountLength;
或
我们必须通过完整路径引用 UDF,如下所示:
d = FOREACH dept GENERATE dept_no, com.pig.utility.CountLength(d_name) as length;
您的 jar 应该已注册
例如:
REGISTER /home/hadoop/udf.jar;
DEFINE package.CountLength CountLength ;
停机约36小时后找到问题原因...
包名包含“IN”,这对 Pig 来说是个问题。
package com.pig.in.action.assignments.udf;
// ^^
当我把包名改成下面的时候,一切都很好-
package com.pig.nnn.action.assignments.udf;
// ^^^
构建修改后的 UDF 后,我注册了 Jar 并为函数名称和 bingo 定义了一个别名,一切正常 -
REGISTER /user/sgn/UDFs/Pig/CountLength-1.jar;
DEFINE CL com.pig.nnn.action.assignments.udf.CountLength;
. . .
. . .
d = FOREACH dept GENERATE dept_no, CL(d_name) AS DeptLength;
我不记得 IN 是否是 Pig 中的保留字。但是 IN 的存在仍然会导致问题,(至少在 Pig 的 0.14.0 版本中)。
我在 pig 中尝试我的第一个 UDF 并编写了以下函数 -
package com.pig.in.action.assignments.udf;
import org.apache.pig.EvalFunc;
import org.apache.pig.PigWarning;
import org.apache.pig.data.Tuple;
import java.io.IOException;
public class CountLength extends EvalFunc<Integer> {
public Integer exec(Tuple inputVal) throws IOException {
// Validate Input Value ...
if (inputVal == null ||
inputVal.size() == 0 ||
inputVal.get(0) == null) {
// Emit warning text for user, and skip this iteration
super.warn("Inappropriate parameter, Skipping ...",
PigWarning.SKIP_UDF_CALL_FOR_NULL);
return null;
}
// Count # of characters in this string ...
final String inputString = (String) inputVal.get(0);
return inputString.length();
}
}
但是,当我尝试按如下方式使用它时,Pig 会抛出一条错误消息,至少在我的 UDF 上下文中它不容易理解:
grunt> cat dept.txt;
10,ACCOUNTING,NEW YORK
20,RESEARCH,DALLAS
30,SALES,CHICAGO
40,OPERATIONS,BOSTON
grunt> dept = LOAD '/user/sgn/dept.txt' USING PigStorage(',') AS (dept_no: INT, d_name: CHARARRAY, d_loc: CHARARRAY);
grunt> d = FOREACH dept GENERATE dept_no, com.pig.in.action.assignments.udf.CountLength(d_name);
2015-06-02 16:24:13,416 [main] ERROR org.apache.pig.tools.grunt.Grunt - ERROR 1200: <line 2, column 79> mismatched input '(' expecting SEMI_COLON
Details at logfile: /home/sgn/pig_1433261973141.log
谁能帮我弄清楚这是怎么回事?
我已经阅读了文档,但在我看来上面的示例中没有明显的错误。我在这里遗漏了什么吗?
这些是我在 pom.xml 中使用的库:
<dependency>
<groupId>org.apache.pig</groupId>
<artifactId>pig</artifactId>
<version>0.14.0</version>
</dependency>
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-core</artifactId>
<version>1.2.1</version>
</dependency>
是否存在兼容性问题?
谢谢,
-Vipul Pathak;
试过上面的例子。只要使用 REGISTER 命令注册了 jar 并且 jar 在 classpath 中可用,我们就不会看到任何错误。
REGISTER myudfs.jar;
dept = LOAD 'a.csv' USING PigStorage(',') AS (dept_no: INT, d_name: CHARARRAY, d_loc: CHARARRAY);
d = FOREACH dept GENERATE dept_no, CountLength(d_name) as length;
输入:a.csv
10,ACCOUNTING,NEW YORK
20,RESEARCH,DALLAS
30,SALES,CHICAGO
40,OPERATIONS,BOSTON
输出:d
(10,10)
(20,8)
(30,5)
(40,10)
N.B。 : 在上面 运行 中 class CountLength 已经在默认包中定义。
如果此 class - CountLength 已在包中定义 com.pig.utility 那么要访问 UDF,我们必须有如下的 DEFINE 语句
DEFINE CountLength com.pig.utility.CountLength;
或
我们必须通过完整路径引用 UDF,如下所示:
d = FOREACH dept GENERATE dept_no, com.pig.utility.CountLength(d_name) as length;
您的 jar 应该已注册 例如:
REGISTER /home/hadoop/udf.jar;
DEFINE package.CountLength CountLength ;
停机约36小时后找到问题原因...
包名包含“IN”,这对 Pig 来说是个问题。
package com.pig.in.action.assignments.udf;
// ^^
当我把包名改成下面的时候,一切都很好-
package com.pig.nnn.action.assignments.udf;
// ^^^
构建修改后的 UDF 后,我注册了 Jar 并为函数名称和 bingo 定义了一个别名,一切正常 -
REGISTER /user/sgn/UDFs/Pig/CountLength-1.jar;
DEFINE CL com.pig.nnn.action.assignments.udf.CountLength;
. . .
. . .
d = FOREACH dept GENERATE dept_no, CL(d_name) AS DeptLength;
我不记得 IN 是否是 Pig 中的保留字。但是 IN 的存在仍然会导致问题,(至少在 Pig 的 0.14.0 版本中)。