UDTF示例 import com.aliyun.odps.udf.UDFException;
import com.aliyun.odps.udf.UDTF;
import com.aliyun.odps.udf.annotation.Resolve;
import org.json.JSONException;
import org.json.JSONObject;
@Resolve("STRING,*->STRING,*")
public class JsonTuple extends UDTF {
private Object[] result = null;
@Override
public void process(Object[] input) throws UDFException {
if (result == null) {
result = new Object[input.length];
}
try {
JSONObject obj = new JSONObject((String)input[0]);
for (int i = 1; i < input.length; i++) {
// 返回值要求变长部分都是STRING。
result[i] = String.valueOf(obj.get((String)(input[i])));
}
result[0] = null;
} catch (JSONException ex) {
for (int i = 1; i < result.length; i++) {
result[i] = null;
}
result[0] = ex.getMessage();
}
forward(result);
}
}以上UDTF示例中,返回值个数会根据输入参数的个数来决定。输出参数中的第一个参数是一个JSON文本,后面的参数是需要从JSON中解析的Key。返回值中的第一个返回值是解析JSON过程中的出错信息,如果没有出错,则会根据输入的Key依次输出从JSON中解析出来的内容。使用示例如下。
-- 根据输入参数的个数定制输出别名个数。
SELECT my_json_tuple(json, 'a', 'b') as exceptions, a, b FROM jsons;
-- 变长部分可以一列都没有。
SELECT my_json_tuple(json) as exceptions, a, b FROM jsons;
-- 下面这个SQL会出现运行时错误,因为别名个数与实际输出个数不符。
-- 注意编译时无法发现这个错误。
SELECT my_json_tuple(json, 'a', 'b') as exceptions, a, b, c FROM jsons; 当本文介绍的这些扩展无法满足您的业务需求时,建议您使用UDT实现聚合函数和UDTF的功能。详情请参见UDT概述。
说明 UDAF和UDTF的Python版本示例请参见Python 3 UDAF和Python 3 UDTF读取MaxCompute资源示例。
|