一、背景介绍: MaxCompute 2.0版本升级后,Java UDF支持的数据类型从原来的BIGINT、STRING、DOUBLE、BOOLEAN扩展了更多基本的数据类型,同时还扩展支持了ARRAY、MAP、STRUCT等复杂类型,以及Writable参数。Java UDF使用复杂数据类型的方法,STRUCT对应com.aliyun.odps.data.Struct。com.aliyun.odps.data.Struct从反射看不出Field Name和Field Type,所以需要用@Resolve注解来辅助。即如果需要在UDF中使用STRUCT,要求在UDF Class上也标注上@Resolve注解。但是当我们Struct类型中的field有很多字段的时候,这个时候需要我们去手动的添加@Resolve注解就不是那么的友好。针对这一个问题,我们可以使用Hive 中的GenericUDF去实现。MaxCompute 2.0支持Hive风格的UDF,部分Hive UDF、UDTF可以直接在MaxCompute上使用。二、复杂数据类型UDF示例 示例定义了一个有三个复杂数据类型的UDF,其中第一个用ARRAY作为参数,第二个用MAP作为参数,第三个用STRUCT作为参数。由于第三个Overloads用了STRUCT作为参数或者返回值,因此要求必须对UDF Class添加@Resolve注解,指定STRUCT的具体类型。1.代码编写
@Resolve("struct,string->string")
public class UdfArray extends UDF {
public String evaluate(List vals, Long len) {
return vals.get(len.intValue());
}
public String evaluate(Map map, String key) {
return map.get(key);
}
public String evaluate(Struct struct, String key) {
return struct.getFieldValue("a") + key;
}
}
2.打jar包添加资源
add jar UdfArray.jar
3.创建函数
create function my_index as 'UdfArray' using 'UdfArray.jar';
4.使用UDF函数
select id, my_index(array('red', 'yellow', 'green'), colorOrdinal) as color_name from colors;
三、使用Hive的GenericUDF 这里我们使用Struct复杂数据类型作为示例,主要处理的逻辑是当我们结构体中两个字段前后没有差异时不返回,如果前后有差异将新的字段及其值组成新的结构体返回。示例中Struct的Field为3个。使用GenericUDF方式可以解决需要手动添加@Resolve注解。1.创建一个MaxCompute表
CREATE TABLE IF NOT EXISTS `tmp_ab_struct_type_1` (
`a1` struct,
`b1` struct
);
2.表中数据结构如下
insert into table tmp_ab_struct_type_1 SELECT named_struct('a',1,'b',3,'c','2019-12-17 16:27:00'), named_struct('a',5,'b',6,'c','2019-12-18 16:30:00');
查询数据如下所示:
3.编写GenericUDF处理逻辑 (1)QSC_DEMOO类
package com.aliyun.udf.struct;
import org.apache.hadoop.hive.ql.exec.UDFArgumentException;
import org.apache.hadoop.hive.ql.exec.UDFArgumentTypeException;
import org.apache.hadoop.hive.ql.metadata.HiveException;
import org.apache.hadoop.hive.ql.udf.generic.GenericUDF;
import org.apache.hadoop.hive.serde2.objectinspector.ObjectInspector;
import org.apache.hadoop.hive.serde2.objectinspector.ObjectInspectorFactory;
import org.apache.hadoop.hive.serde2.objectinspector.StructField;
import org.apache.hadoop.hive.serde2.objectinspector.StructObjectInspector;
import java.util.ArrayList;
import java.util.List;
/**
* Created by ljw on 2019-12-17
* Description:
*/
@SuppressWarnings("Duplicates")
public class QSC_DEMOO extends GenericUDF {
StructObjectInspector soi1;
StructObjectInspector soi2;
/**
* 避免频繁Struct对象
*/
private PubSimpleStruct resultStruct = new PubSimpleStruct();
private List
关注
打赏