我想知道我是否可以在Tajo中编写UDF,尤其是在Python中。我的用例是ETL,我希望按一些ID(浏览器ID)对日志记录进行分组,然后按时间戳对同一组中的记录进行排序,最后使用我的UDF遍历每个组中的已排序记录。
答案 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功能,允许用户很快在运行时添加功能。