Refer to:http://blog.csdn.net/wf1982/article/details/7623708
1.介绍
UDTF(User-Defined Table-Generating Functions) 用来解决 输入一行输出多行(On-to-many maping) 的需求。同时,也可以解决一列拆分成多列的问题(Hive支持复杂的数据格式,包括List)。
2.编写需要的UDTF
1) 继承org.apache.hadoop.hive.ql.udf.generic.GenericUDTF。
2) 实现initialize, process, close三个方法
3) UDTF首先会调用initialize方法,此方法返回UDTF的返回行的信息(返回个数,类型)。
初始化完成后,会调用process方法,对传入的参数进行处理,可以通过forword()方法把结果返回。
最后close()方法调用,对需要清理的方法进行清理。
这是一个用来切分 key:value;key:value 这种字符串,返回结果为key, value两个字段。
import java.util.ArrayList; import org.apache.hadoop.hive.ql.udf.generic.GenericUDTF; import org.apache.hadoop.hive.ql.exec.UDFArgumentException; import org.apache.hadoop.hive.ql.exec.UDFArgumentLengthException; import org.apache.hadoop.hive.ql.metadata.HiveException; import org.apache.hadoop.hive.serde2.objectinspector.ObjectInspector; import org.apache.hadoop.hive.serde2.objectinspector.ObjectInspectorFactory; import org.apache.hadoop.hive.serde2.objectinspector.StructObjectInspector; import org.apache.hadoop.hive.serde2.objectinspector.primitive.PrimitiveObjectInspectorFactory; public class ExplodeMap extends GenericUDTF{ @Override public void close() throws HiveException { // TODO Auto-generated method stub } @Override public StructObjectInspector initialize(ObjectInspector[] args) throws UDFArgumentException { if (args.length != 1) { throw new UDFArgumentLengthException("ExplodeMap takes only one argument"); } if (args[0].getCategory() != ObjectInspector.Category.PRIMITIVE) { throw new UDFArgumentException("ExplodeMap takes string as a parameter"); } ArrayList<String> fieldNames = new ArrayList<String>(); ArrayList<ObjectInspector> fieldOIs = new ArrayList<ObjectInspector>(); fieldNames.add("col1"); fieldOIs.add(PrimitiveObjectInspectorFactory.javaStringObjectInspector); fieldNames.add("col2"); fieldOIs.add(PrimitiveObjectInspectorFactory.javaStringObjectInspector); return ObjectInspectorFactory.getStandardStructObjectInspector(fieldNames,fieldOIs); } @Override public void process(Object[] args) throws HiveException { String input = args[0].toString(); String[] test = input.split(";"); for(int i=0; i<test.length; i++) { try { String[] result = test[i].split(":"); forward(result); } catch (Exception e) { continue; } } } }
3. 使用方法
UDTF有两种使用方法,一种直接放到select后面,一种和lateral view一起使用。
1) 直接select中使用:select explode_map(properties) as (col1,col2) from src;
不可以添加其他字段使用:select a, explode_map(properties) as (col1,col2) from src
不可以嵌套调用:select explode_map(explode_map(properties)) from src
不可以和group by/cluster by/distribute by/sort by一起使用:select explode_map(properties) as (col1,col2) from src group by col1, col2
2) 和lateral view一起使用:
select src.id, mytable.col1, mytable.col2 from src lateral view explode_map(properties) mytable as col1, col2;
此方法更为方便日常使用。执行过程相当于单独执行了两次抽取,然后union到一个表里。
4. 参考文档
http://wiki.apache.org/hadoop/Hive/LanguageManual/UDF
http://wiki.apache.org/hadoop/Hive/DeveloperGuide/UDTF
http://www.slideshare.net/pauly1/userdefined-table-generating-functions
Appendix:
一个用于将字符串拆分成多个字段的:
import java.util.ArrayList; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.hadoop.hive.ql.exec.Description; import org.apache.hadoop.hive.ql.exec.UDFArgumentException; import org.apache.hadoop.hive.ql.exec.UDFArgumentLengthException; import org.apache.hadoop.hive.ql.metadata.HiveException; import org.apache.hadoop.hive.ql.udf.generic.GenericUDTF; import org.apache.hadoop.hive.serde2.objectinspector.ObjectInspector; import org.apache.hadoop.hive.serde2.objectinspector.ObjectInspectorFactory; import org.apache.hadoop.hive.serde2.objectinspector.StructObjectInspector; import org.apache.hadoop.hive.serde2.objectinspector.primitive.PrimitiveObjectInspectorFactory; import org.apache.hadoop.hive.serde2.objectinspector.primitive.WritableConstantIntObjectInspector; /** * GenericUDTFRD: this * */ @Description(name = "tr_rd", value = "_FUNC_(x)") public class GenericUDTFRD extends GenericUDTF { private static Log LOG = LogFactory.getLog(GenericUDTFRD.class.getName()); @Override public void close() throws HiveException { } @Override public StructObjectInspector initialize(ObjectInspector[] args) throws UDFArgumentException { LOG.debug("========================initialize"); LOG.debug("args.length" + args.length); if (args.length != 2) { throw new UDFArgumentLengthException( "ExplodeMap takes only two argument"); } WritableConstantIntObjectInspector x = (WritableConstantIntObjectInspector) args[1]; int numCols = x.getWritableConstantValue().get(); LOG.debug("numCols:" + numCols); // construct output object inspector ArrayList<String> fieldNames = new ArrayList<String>(numCols); ArrayList<ObjectInspector> fieldOIs = new ArrayList<ObjectInspector>( numCols); for (int i = 0; i < numCols; ++i) { fieldNames.add("c" + i); fieldOIs.add(PrimitiveObjectInspectorFactory.javaStringObjectInspector); } return ObjectInspectorFactory.getStandardStructObjectInspector( fieldNames, fieldOIs); } @Override public void process(Object[] o) throws HiveException { LOG.debug("========================process"); String input = o[0].toString(); //字段分隔符 String[] test = input.split("\t"); LOG.debug("input:" + input); LOG.debug("test:" + test); for(int i=0;i<test.length;i++){ if("".equals(test[i])||null==test[i]){ test[i]="\\N"; } } forward(test); } @Override public String toString() { return "tr_rd"; } }
用法是:
--将一个字段,拆分成3个。 select tr_rd(tt.col1,3) as (c1,c2,c3) from table tt
相关推荐
此Hive UDTF将复制第一个输入列 一种。 如何制作罐子 mvn package ## b。 准备一个带有示例数据的Hive表 在Hive CLI中,创建测试表: create table testudtf (a string, b string) ROW FORMAT DELIMITED FIELDS ...
hive编写 udf 至少需要引入的jar包:hive-exec-xxx.jar 和 hadoop-core-xxx.jar
6.2 UDTF 39 6.2.1 Explode 39 7. HIVE 的MAP/REDUCE 41 7.1 JOIN 41 7.2 GROUP BY 42 7.3 DISTINCT 42 8. 使用HIVE注意点 43 8.1 字符集 43 8.2 压缩 43 8.3 count(distinct) 43 8.4 JOIN 43 8.5 DML操作 44 8.6 ...
6.2 UDTF 39 6.2.1 Explode 39 7. HIVE 的MAP/REDUCE 41 7.1 JOIN 41 7.2 GROUP BY 42 7.3 DISTINCT 42 8. 使用HIVE注意点 43 8.1 字符集 43 8.2 压缩 43 8.3 count(distinct) 43 8.4 JOIN 43 8.5 DML操作 44 8.6 ...
hive所有函数 包括UDTs、UDAF、UDTF函数和运算符等,中文汉化,翻译并测试
UDTF函数不生效问题
获取最大分区UDTF函数
解析Json函数UDTF函数2
解析Json函数UDTF函数1
* 自定义函数(UDF/UDAF/UDTF) Hive的缺点包括: * 默认M/R为执行引擎,M/R启动有延迟延迟较高 * 不支持物化视图 * 不适用OLTP * 暂不支持存储过程 Hive的应用场景包括: * 数据挖掘 * 非实时分析 * 日志分析 *...
Hive常用数据类型介绍,表创建,内外部表、分区分桶表介绍,hive内置函数,UDTF,UDAF函数介绍,hive数据的导入导出以及JDBC配置方法。详细介绍了hive一些函数的使用和应用。
* 可扩充 UDF/UDAF/UDTF Hive 的缺点包括: * 延迟较高,性能有提升空间 * 不支持事务类操作 Hive 提供数据提取、转换、加载功能,并可用类似于 SQL 的语法,对 HDFS 海量数据库中的数据进行查询统计等操作。Hive...
Hive函数学习指南 Hive是一个基于Hadoop的数据仓库工具,用于存储、...Hive也支持用户自定义函数,可以根据实际使用场景编写函数,如UDF、UDTF和UDAF。用户可以使用Java语言实现自定义函数,然后在Hive中注册和使用。
hive列转行 1.函数说明 EXPLODE(col):将 hive 一列中复杂的 array 或者 map 结构拆分成多行。 LATERAL VIEW : 用法:LATERAL VIEW udtf(expression) tableAlias AS columnAlias 解释:用于和 split, explode 等 ...
Hive是基于Hadoop的一个数据仓库工具,将繁琐的MapReduce程序变成了简单方便的SQL语句实现,深受广大软件开发工程师喜爱。...更新:课件升级、添加自定义UDTF函数、企业常用函数以及更多企业面试真题详细讲解
Apache Hive(TM)数据仓库软件有助于查询和... HiveQL还可以使用自定义标量函数(UDF),聚合(UDAF)和表函数(UDTF)进行扩展。https://mirrors.tuna.tsinghua.edu.cn/apache/hive/hive-standalone-metastore-3.0.0/
hive-udfhive自定义函数主要实现hive3种自定义函数1,udf函数,主要用于处理一对一数据处理2,udtf函数,主要用于处理一对多数据处理2,udaf函数,主要用与处理多对一数据聚合处理