无法调用接受Tuple输入的Java UDF

时间:2013-07-02 13:42:56

标签: apache-pig

我无法理解调用接受Tuple作为输入的Java UDF的方法。

gsmCell = LOAD '$gsmCell' using PigStorage('\t') as
          (branchId,
           cellId: int,
           lac: int,
           lon: double,
           lat: double
          );

gsmCellFiltered = FILTER gsmCell BY     cellId     is not null and
                                        lac        is not null and
                                        lon        is not null and
                                        lat        is not null;

gsmCellFixed = FOREACH gsmCellFiltered GENERATE FLATTEN (pig.parser.GSMCellParser(* ) )  as
                                                (cellId: int,
                                                 lac: int,
                                                 lon: double,
                                                 lat: double,
                                                );

当我使用()包装GSMCellParser的输入时,我进入UDF: 元组(元组)。 Pig确实将所有字段都包含在元组中并将其置于一个元组内。

当我尝试传递字段列表时,请使用*或$ 0 ..我确实得到例外:

sed by: org.apache.pig.impl.logicalLayer.validators.TypeCheckerException: ERROR 1045: 
<line 28, column 57> Could not infer the matching function for pig.parser.GSMCellParser as multiple or none of them fit. Please use an explicit cast.
    at org.apache.pig.newplan.logical.visitor.TypeCheckingExpVisitor.visit(TypeCheckingExpVisitor.java:761)
    at org.apache.pig.newplan.logical.expression.UserFuncExpression.accept(UserFuncExpression.java:88)
    at org.apache.pig.newplan.ReverseDependencyOrderWalker.walk(ReverseDependencyOrderWalker.java:70)
    at org.apache.pig.newplan.PlanVisitor.visit(PlanVisitor.java:52)
    at org.apache.pig.newplan.logical.visitor.TypeCheckingRelVisitor.visitExpressionPlan(TypeCheckingRelVisitor.java:191)
    at org.apache.pig.newplan.logical.visitor.TypeCheckingRelVisitor.visit(TypeCheckingRelVisitor.java:157)
    at org.apache.pig.newplan.logical.relational.LOGenerate.accept(LOGenerate.java:246)

我做错了什么? 我的目标是用元组提供我的UDF。元组应包含字段列表。 (即元组的大小应为4:cellid,lac,lon.lat)

UPD: 我试过GROUP ALL:

--filter non valid records
gsmCellFiltered = FILTER gsmCell BY     cellId     is not null and
                                        lac        is not null and
                                        lon        is not null and
                                        lat        is not null and
                                        azimuth    is not null and
                                        angWidth   is not null;

gsmCellFilteredGrouped = GROUP gsmCellFiltered ALL;

--fix records
gsmCellFixed = FOREACH gsmCellFilteredGrouped GENERATE FLATTEN                  (pig.parser.GSMCellParser($1))  as
                                                        (cellId: int,
                                                         lac: int,
                                                         lon: double,
                                                         lat: double,
                                                         azimuth: double,
                                                         ppw,
                                                         midDist: double,
                                                         maxDist,
                                                         cellType: chararray,
                                                         angWidth: double,
                                                         gen: chararray,
                                                         startAngle: double
                                                        );



Caused by: org.apache.pig.impl.logicalLayer.validators.TypeCheckerException: ERROR 1045: 
<line 27, column 64> Could not infer the matching function for pig.parser.GSMCellParser as multiple or none of them fit. Please use an explicit cast.

此UDF的输入架构是:Tuple 我不明白这个主意。 元组是一组有序的文件。 LOAD函数向我返回一个元组。 我想将整个元组传递给我的UDF。

1 个答案:

答案 0 :(得分:1)

T EvalFunc<T>.eval(Tuple)方法的签名中,您可以看到所有EvalFunc UDF都传递了一个元组 - 这个元组包含传递给UDF的所有参数。

在你的情况下,调用GSMCellParser(*)意味着元组的第一个参数将是当前正在处理的元组(因此元组中的元组)。

从概念上讲,如果你希望元组只包含你应该调用GSMCellParser(cellid, lac, lat, lon)的字段,那么传递给eval func的元组将具有(int, int, double, double)的模式。这也使你的元组编码更容易,因为你不必从传递的'元组中的元组'中删除字段,而是你知道字段0是cellid,字段1是lac等等。