Struct复杂数据类型的UDF编写、兼容HIVE的GenericUDF编写

一、背景介绍:
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<a:bigint>,string->string")
public class UdfArray extends UDF {
public String evaluate(List<String> vals, Long len) {return vals.get(len.intValue());
}
public String evaluate(Map<String,String> 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<a:STRING,b:STRING,c:string>,
`b1` struct<a:STRING,b:STRING,c:string>
);

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');

查询数据如下所示:

1576811346298_FEB20147-DD74-4a10-8D6E-780D91DCBC93.png

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<? extends StructField> allStructFieldRefs;//1. 这个方法只调用一次,并且在evaluate()方法之前调用。该方法接受的参数是一个arguments数组。该方法检查接受正确的参数类型和参数个数。//2. 输出类型的定义@Overridepublic ObjectInspector initialize(ObjectInspector[] arguments) throws UDFArgumentException {String error = "";//检验参数个数是否正确if (arguments.length != 2) {throw new UDFArgumentException("需要两个参数");}//判断参数类型是否正确-structObjectInspector.Category arg1 = arguments[0].getCategory();ObjectInspector.Category arg2 = arguments[1].getCategory();if (!(arg1.equals(ObjectInspector.Category.STRUCT))) {error += arguments[0].getClass().getSimpleName();throw new UDFArgumentTypeException(0, "\"array\" expected at function STRUCT_CONTAINS, but \"" +arg1.name() + "\" " + "is found" + "\n" + error);}if (!(arg2.equals(ObjectInspector.Category.STRUCT))) {error += arguments[1].getClass().getSimpleName();throw new UDFArgumentTypeException(0, "\"array\" expected at function STRUCT_CONTAINS, but \""+ arg2.name() + "\" " + "is found" + "\n" + error);}//输出结构体定义ArrayList<String> structFieldNames = new ArrayList();ArrayList<ObjectInspector> structFieldObjectInspectors = new ArrayList();soi1 = (StructObjectInspector) arguments[0];soi2 = (StructObjectInspector) arguments[1];StructObjectInspector toValid = null;if (soi1 == null)toValid = soi2;else toValid = soi1;//设置返回类型allStructFieldRefs = toValid.getAllStructFieldRefs();for (StructField structField : allStructFieldRefs) {structFieldNames.add(structField.getFieldName());structFieldObjectInspectors.add(structField.getFieldObjectInspector());}return ObjectInspectorFactory.getStandardStructObjectInspector(structFieldNames, structFieldObjectInspectors);}//这个方法类似UDF的evaluate()方法。它处理真实的参数,并返回最终结果。@Overridepublic Object evaluate(DeferredObject[] deferredObjects) throws HiveException {//将hive中的struct类型转换成com.aliyun.odps.data.Struct, 如果有错误,请调试,查看deferredObjects的数据是什么样子的//然后自己进行重新封装 !!!ArrayList list1 = (ArrayList) deferredObjects[0].get();ArrayList list2 = (ArrayList) deferredObjects[1].get();int len = list1.size();ArrayList fieldNames = new ArrayList<>();ArrayList fieldValues = new ArrayList<>();for (int i = 0; i < len ; i++) {if (!list1.get(i).equals(list2.get(i))) {fieldNames.add(allStructFieldRefs.get(i).getFieldName());fieldValues.add(list2.get(i));}}if (fieldValues.size() == 0) return null;return fieldValues;}//这个方法用于当实现的GenericUDF出错的时候,打印出提示信息。而提示信息就是你实现该方法最后返回的字符串。@Overridepublic String getDisplayString(String[] strings) {return "Usage:" + this.getClass().getName() + "(" + strings[0] + ")";}
}

(2)PubSimpleStruct类

package com.aliyun.udf.struct;
import com.aliyun.odps.data.Struct;
import com.aliyun.odps.type.StructTypeInfo;
import com.aliyun.odps.type.TypeInfo;
import java.util.List;public class PubSimpleStruct implements Struct {private StructTypeInfo typeInfo;private List<Object> fieldValues;public StructTypeInfo getTypeInfo() {return typeInfo;}public void setTypeInfo(StructTypeInfo typeInfo) {this.typeInfo = typeInfo;}public void setFieldValues(List<Object> fieldValues) {this.fieldValues = fieldValues;}public int getFieldCount() {return fieldValues.size();}public String getFieldName(int index) {return typeInfo.getFieldNames().get(index);}public TypeInfo getFieldTypeInfo(int index) {return typeInfo.getFieldTypeInfos().get(index);}public Object getFieldValue(int index) {return fieldValues.get(index);}public TypeInfo getFieldTypeInfo(String fieldName) {for (int i = 0; i < typeInfo.getFieldCount(); ++i) {if (typeInfo.getFieldNames().get(i).equalsIgnoreCase(fieldName)) {return typeInfo.getFieldTypeInfos().get(i);}}return null;}public Object getFieldValue(String fieldName) {for (int i = 0; i < typeInfo.getFieldCount(); ++i) {if (typeInfo.getFieldNames().get(i).equalsIgnoreCase(fieldName)) {return fieldValues.get(i);}}return null;}public List<Object> getFieldValues() {return fieldValues;}@Overridepublic String toString() {return "PubSimpleStruct{" +"typeInfo=" + typeInfo +", fieldValues=" + fieldValues +'}';}
}

3、打jar包,添加资源

add jar test.jar;

4、创建函数

CREATE FUNCTION UDF_DEMO as 'com.aliyun.udf.test.UDF_DEMOO' using 'test.jar';

5、测试使用UDF函数

set odps.sql.hive.compatible=true;
select UDF_DEMO(a1,b1) from tmp_ab_struct_type_1;

查询结果如下所示:

 

1576811361785_5BC15482-A394-4353-9E17-D6A53AB54960.png


注意:
(1)在使用兼容的Hive UDF的时候,需要在SQL前加set odps.sql.hive.compatible=true;语句,set语句和SQL语句一起提交执行。

(2)目前支持兼容的Hive版本为2.1.0,对应Hadoop版本为2.7.2。如果UDF是在其他版本的Hive/Hadoop开发的,则可能需要使用此Hive/Hadoop版本重新编译。
有疑问可以咨询阿里云MaxCompute技术支持:刘建伟

    <dependency><groupId>org.apache.hadoop</groupId><artifactId>hadoop-common</artifactId><version>2.7.2</version></dependency><dependency><groupId>org.apache.hive</groupId><artifactId>hive-exec</artifactId><version>2.1.0</version></dependency>

欢迎加入“MaxCompute开发者社区2群”,点击链接申请加入或扫描二维码
https://h5.dingtalk.com/invite-page/index.html?bizSource=____source____&corpId=dingb682fb31ec15e09f35c2f4657eb6378f&inviterUid=E3F28CD2308408A8&encodeDeptId=0054DC2B53AFE745
6766293bc74543c99e7c493dc15cd39b.png

原文链接
本文为云栖社区原创内容,未经允许不得转载。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/516722.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

如何跨项目工作空间访问MaxCompute资源和函数?

1、背景介绍 同一个主账号下面的两个工作空间&#xff0c;工作空间名称分别为 A工作空间名称:wei_wwww A工作空间子账号&#xff1a;mc_oss B工作空间名称:wei_mc B工作空间子账号&#xff1a;bigdata_wei 现在B工作空间子账号bigdata_wei需要访问A工作空间子账号mc_oss创建的U…

Nexus 3.31.1 maven 私服 仓库和IntelliJ IDEA 2021.2 实战篇 linux

文章目录一、maven配置1. 私服配置2. 替换后的配置二、IntelliJ IDEA2.1. 创建项目2.2. 指定配置2.3. 下载依赖三、nexus3 监控3.1. 查看依赖版本3.2. 版本对比3.3. aliyun 仓库地址一、maven配置 1. 私服配置 在本地的maven 配置settings.xml内容&#xff0c;用下面内容覆盖…

我把这篇文章给女朋友看,她终于明白什么是「数据中台」了

来源 | 智领云科技责编 | Carol封图 | CSDN 下载自视觉中国这几天&#xff0c;女朋友一直忙着为自己挑选情人节礼物&#xff0c;毕竟直男的审美她也觉得不靠谱。就在昨天&#xff0c;她气冲冲地跑过来问我&#xff1a;为什么有些平台总是推荐一些我不喜欢的东西&#xff1f;为什…

发光的二次元克拉克拉 满足年轻用户个性化、碎片化的文娱需求

克拉克拉&#xff08;KilaKila&#xff09;是国内专注二次元、主打年轻用户的娱乐互动内容社区软件。KilaKila 推出互动语音直播、短视频配音、对话小说等功能&#xff0c;满足当下年轻用户个性化、碎片化的文娱需求。随着业务规模增长&#xff0c;海量数据存储与计算的瓶颈也日…

Nexus 3.31.1 maven 私服 服务器配置篇 linux

文章目录一、以服务运行1. 编写配置2. 赋予可执行权限3. 配置自启动4. 启动nexus5. 监控状态6. 停止服务二、配置文件说明2.1. JAVA配置2.2. 自定义配置2.3. 工作/日志 目录修改三、使用nginx代理3.1. HTTP3.2. HTTPS四、其他配置4.1. 配置匿名访问4.2. 更改管理员电子邮件地址…

混合云模式助力斗鱼搭建混搭大数据架构

云栖号案例库&#xff1a;【点击查看更多上云案例】 不知道怎么上云&#xff1f;看云栖号案例库&#xff0c;了解不同行业不同发展阶段的上云方案&#xff0c;助力你上云决策&#xff01; 案例背景 2019杭州云栖大会大数据企业级服务专场&#xff0c;由斗鱼大数据高级专家张龙…

架构师技术文档:Redis+Nginx+Spring全家桶+Dubbo精选

最近花了很长的时间去搜罗整理Java核心技术好文&#xff0c;我把每个Java核心技术的优选文章都整理成了一个又一个的文档。今天就把这些东西分享给老铁们&#xff0c;也能为老铁们省去不少麻烦&#xff0c;想学什么技能了&#xff0c;遇到哪方面的问题了 直接打开文档学一学就好…

天弘基金交易数据清算从8小时缩至1.5小时 解决余额宝算力难题

天弘基金作为国内总规模最大的公募基金&#xff0c;阿里云MaxCompute为我们构建了企业级一站式大数据解决方案。MaxCompute对于海量数据的存储、运维、计算能力强大且安全稳定&#xff0c;MaxCompute服务将原本需要清算8小时的用户交易数据缩短至清算1个半小时&#xff0c;同时…

配置MaxCompute任务消费监控告警,避免资源过度消费

MaxCompute 按量计费资源为弹性伸缩资源&#xff0c;对于计算任务&#xff0c;按任务需求提供所需资源&#xff0c;对资源使用无限制&#xff0c;同时MaxCompute按量计费的账单为天账单&#xff0c;即当天消费需要第二天才出账&#xff0c;因此&#xff0c;有必要对计算任务的消…

Vue3.0 备受热捧!2020 前端开发进阶必读

你好&#xff0c;我是汤小洋。前华为全栈工程师&#xff0c;南京大学软件工程硕士&#xff0c;拥有11年全栈开发及内部培训分享经验。作为一名前端人&#xff0c;学习从不是一件容易的事&#xff0c;这是我一路走过来的真实感受。“只要付出&#xff0c;就有收获”、“只要努力…

Docker 查看日志记录

日志文件对于处理故障十分重要&#xff0c;对于docker容器如何查看日志呢 查看docker容器的日志用到的是docker logs这个命令&#xff1a; 先看下官方给的命令说明 docker logs --help–details 显示更多的信息 –f, --follow 跟踪实时日志–since string 显示自某个timestam…

Docker JFrog Artifactory 7.27.10 maven私服(仓库配置篇)

文章目录一、二、 建立远程仓库2.1. 仓库列表2.2. 仓库创建演示2.3. 阿里云仓里调整三、建立本地仓库3.1. 仓库列表3.2. 仓库创建演示四、创建虚拟库4.1. 仓库列表4.2. 仓库创建演示五、创建用户/组/权限5.1. 创建用户5.2. 创建用户组5.3. 创建权限5.4. 获取密文密码5.5. 生成配…

ODPS2.0重装上阵,优化提升SQL语言表达能力

MaxCompute&#xff08;原ODPS&#xff09;是阿里云自主研发的具有业界领先水平的分布式大数据处理平台, 尤其在集团内部得到广泛应用&#xff0c;支撑了多个BU的核心业务。 MaxCompute除了持续优化性能外&#xff0c;也致力于提升SQL语言的用户体验和表达能力&#xff0c;提高…

野鸡大学怎么知道考生电话的?

来源 | 隐小卫责编 | 晋兆雨封图 | CSDN 下载自视觉中国当你在某度频繁搜索“高考”、“志愿”、“大学”、“本科”等关键词时&#xff0c;你的手机号码等信息有可能被非法抓取。并且打包进行交易&#xff0c;卖给培训班、网校、医院等机构进行所谓的“精准获客”。当然&#…

快速入门ECS快照功能,助力大数据容灾保护

阿里云快照是云盘数据在某个时刻完整的只读拷贝&#xff0c;是一种便捷高效的数据容灾手段&#xff0c;常用于数据备份、制作自定义镜像、应用容灾等。 应用场景 推荐您在以下场景中使用快照&#xff1a; 容灾备份&#xff1a;为云盘创建快照&#xff0c;再使用快照创建云盘获…

Docker JFrog Artifactory 7.27.10 maven私服(IDEA 实战篇01) linux

文章目录一、私服配置1. 账户密码2. 本地仓库3. ip/port二、IntelliJ IDEA2.1. 创建项目2.2. 指定配置2.3. 下载依赖2.4. 依赖查看2.5. 注意事项一、私服配置 将服务端生成的配置复制下来&#xff0c;进行修改 1. 账户密码 2. 本地仓库 3. ip/port 内容&#xff1a; <?xml…

一文看懂专有网络和交换机的定义及关系

在专有网络&#xff08;Virtual Private Cloud&#xff0c;简称VPC&#xff09;中使用云资源前&#xff0c;您必须先创建一个专有网络和交换机。您可以在一个专有网络中创建多个交换机来划分子网。一个专有网络内的子网默认私网互通。 专有网络和交换机 专有网络VPC是您独有的…

2020中关村论坛未来青年论坛:聚焦科技与产业数字化转型,让创新成果落地开花

8月26日&#xff0c;由中关村科技园区管理委员会指导&#xff0c;朝阳区人民政府、未来论坛联合主办&#xff0c;中关村朝阳园管委会承办的“2020中关村论坛未来青年论坛”&#xff0c;在北京举行。 作为2020中关村论坛的首场先锋论坛&#xff0c;2020中关村论坛未来青年论坛聚…

JFrog Artifactory 7.27 上传应用到私服和从maven私服下载制品

文章目录一、上传微服务应用1. 生成配置2. 拷贝配置3. 执行上传4. 验证5. 自定义配置二、下载制品2.1. 获取密文密码2.2. 执行下载一、上传微服务应用 1. 生成配置 生成Artifactory仓库上传配置文件&#xff0c;选择仓库&#xff0c;点击‘Set Me Up’查看部署配置 2. 拷…

阿里云2020上云采购季,你适合买什么云产品?

线下IDC机房成本高? 自建数据库卡、慢&#xff0c;延迟高? 被黑客攻击了怎么办&#xff1f; 今年IT预算没多少? 不知道怎么过等保2.0&#xff1f; 你遇到了哪些问题&#xff1f;来阿里云2020上云采购季&#xff01;主会场请戳&#xff1a;https://www.aliyun.com/sale-…