如何在Tajo中编写UDF

时间:2014-11-28 19:08:34

标签: etl apache-tajo

我想知道我是否可以在Tajo中编写UDF,尤其是在Python中。我的用例是ETL,我希望按一些ID(浏览器ID)对日志记录进行分组,然后按时间戳对同一组中的记录进行排序,最后使用我的UDF遍历每个组中的已排序记录。

1 个答案:

答案 0 :(得分:1)

我是Tajo PMC会员。感谢您对Tajo的兴趣。

目前,Tajo还不支持Python UDF。但是,Tajo旨在为每个单个函数签名提供多个UDF函数实现。 Python函数UDF功能可以轻松添加到Tajo中。

现在,您应该使用基于Java的自定义函数。有两种方法可以实现自定义UDF。当然,这两种方式都很容易。

第一种方法是使用传统的Tajo UDF接口。以这种方式,每个函数实现应该是一个继承GeneralFunction类的类。 eval()是每个UDF实现的主体。一个例子如下:

@Description(
  functionName = "pow",
  description = "x raised to the power of y",
  example = "> SELECT pow(9.0, 3.0)\n"
           + "729",
  returnType = FLOAT8,
  paramTypes = {
      @ParamTypes(paramTypes = {FLOAT8, FLOAT8})
  }
)
public class Pow extends GeneralFunction {
  public Pow() {
    super(new Column[] {
        new Column("x", FLOAT8),
        new Column("y", FLOAT8)
    });
  }

  @Override
  public Datum eval(Tuple params) {
    Datum value1Datum = params.get(0);
    Datum value2Datum = params.get(1);
    if(value1Datum instanceof NullDatum || value2Datum instanceof NullDatum) {
      return NullDatum.get();
    }

    return DatumFactory.createFloat8(Math.pow(value1Datum.asFloat8(), value2Datum.asFloat8()));
  }
}

另一种方法是使用新的功能界面。通过这种方式,您只需为每个UDF实现一个静态方法。函数的每个静态方法都可以有一个或多个Java原始类型或Java对象类型参数。

根据每个参数是原始参数还是对象类型,每个参数都有一个隐含不同的效果。基本类型参​​数不允许NULL值。在这种情况下,如果参数采用NULL值,则此函数将自动返回NULL值而不实际调用该函数。使用SQL的三值逻辑,像这样的NULL处理在SQL函数中非常常见。所以,基本上,Tajo提供此功能。

具有基本参数的函数示例:

@ScalarFunction(name = "pow", returnType = FLOAT8, paramTypes = {FLOAT8, FLOAT8}) 
public static double pow(double x, double y) { 
  return Math.pow(x, y); 
}

相反,Object类型参数允许NULL值。在这种情况下,每个函数必须显式处理NULL值,如下所示:

@ScalarFunction(name = "pow", returnType = FLOAT8, paramTypes = {FLOAT8, FLOAT8})
public static Double pow(Double x, Double y) {
  if (x == null || y == null) {
    return null;
  }
  return Math.pow(x, y);
}

为了将自己的UDF添加到Tajo集群,您需要创建一个jar文件,包括您自己的函数类。目前,Tajo不允许用户在运行时添加自定义jar。因此,您应该将自定义jar复制到$ {TAJO_HOME} / lib,然后重新启动Tajo集群。

此外,Tajo将支持CREATE FUNCTION功能,允许用户很快在运行时添加功能。