Hive UDF初探
1. 引言
在前一篇中,解决了Hive表中复杂数据结构平铺化以导入Kylin的问题,但是平铺之后计算广告日志的曝光PV是翻倍的,因为一个用户对应于多个标签。所以,为了计算曝光PV,我们得另外创建视图。
分析需求:
- 每个DSP上的曝光PV,标签覆盖的曝光PV;
- 累计曝光PV,累计标签覆盖曝光PV
相当于cube(dsp, tag) + measure(pv),HiveQL如下:
select dsp, tag, count(*) as pv
from ad_view
where view = 'view' and day_time between '2016-04-18' and '2016-04-24'
group by dsp, tag with cube;
现在问题来了:如何将原始表中的tags array<struct<tag:string,label:string,src:string>> 转换成有标签(taged)、无标签(empty)呢?显而易见的办法,为字段tags写一个UDF来判断是否有标签。
2. 实战
基本介绍
user-defined function (UDF)包括:
- 对于字段进行转换操作的函数,如round()、abs()、concat()等;
- 聚集函数user-defined aggregate functions (UDAFs),比如sum()、avg()等;
- 表生成函数user-defined table generating functions (UDTFs),生成多列或多行数据,比如explode()、inline()等
UDTF的使用在与select语句使用时受到了限制,比如,不能与其他的列组合出现:
hive> SELECT name, explode(subordinates) FROM employees;
FAILED: Error in semantic analysis: UDTF's are not supported outside the SELECT clause, nor nested in expressions
Hive提供LATERAL VIEW关键字,对UDTF的输入进行包装(wrap),如此可以达到列组合的效果:
hive> SELECT name, sub
> FROM employees
> LATERAL VIEW explode(subordinates) subView AS sub;
UDF与GenericUDF
org.apache.hadoop.hive.ql.exec.UDF是字段转换操作的基类,提供对于简单数据类型进行转换操作。在实现转换操作时,需要重写evaluate()方法。较UDF抽象类,org.apache.hadoop.hive.ql.udf.generic.GenericUDF提供更为复杂的处理方法类,包括三个方法:
- initialize(ObjectInspector[] arguments),检查输入参数的类型、确定返回值的类型;
- evaluate(DeferredObject[] arguments),字段转换操作的实现函数,其返回值的类型与initialize方法中所指定的返回类型保持一致;
- getDisplayString(String[] children),给Hadoop任务展示debug信息的。
判断tags array<struct<tag:string,label:string,src:string>>是否为空标签(EMPTY)的UDF实现如下:
@Description(name = "checkTag",
value = "_FUNC_(array<struct>) - from the input array of struct "+
"returns the TAGED or EMPTY(no tag).",
extended = "Example:\n"
+ " > SELECT _FUNC_(tags_array) FROM src;")
public class CheckTag extends GenericUDF {
private ListObjectInspector listOI;
public ObjectInspector initialize(ObjectInspector[] arguments) throws UDFArgumentException {
if (arguments.length != 1) {
throw new UDFArgumentLengthException("only takes 1 arguments: List<T>");
}
ObjectInspector a = arguments[0];
if (!(a instanceof ListObjectInspector)) {
throw new UDFArgumentException("first argument must be a list / array");
}
this.listOI = (ListObjectInspector) a;
if(!(listOI.getListElementObjectInspector() instanceof StructObjectInspector)) {
throw new UDFArgumentException("first argument must be a list of struct");
}
return PrimitiveObjectInspectorFactory.javaStringObjectInspector;
}
public Object evaluate(DeferredObject[] arguments) throws HiveException {
if(listOI == null || listOI.getListLength(arguments[0].get()) == 0) {
return "null_field";
}
StructObjectInspector structOI = (StructObjectInspector) listOI.getListElementObjectInspector();
String tag = structOI.getStructFieldData(listOI.getListElement(arguments[0].get(), 0),
structOI.getStructFieldRef("tag")).toString();
if (listOI.getListLength(arguments[0].get()) == 1 && tag.equals("EMPTY")) {
return "EMPTY";
}
return "TAGED";
}
public String getDisplayString(String[] children) {
return "check tag whether is empty";
}
}
还需添加依赖:
<dependency>
<groupId>org.apache.hive</groupId>
<artifactId>hive-exec</artifactId>
<version>0.14.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-common</artifactId>
<version>2.5.0-cdh5.3.2</version>
<scope>provided</scope>
</dependency>
编译后打成jar包,放在HDFS上,然后add jar即可调用该UDF了:
add jar hdfs://path/to/udf-1.0-SNAPSHOT.jar;
create temporary function checktag as 'com.hive.udf.CheckTag';
create view if not exists yooshu_view
partitioned on (day_time)
as
select uid, dsp, view, click, checktag(tags) as tag, day_time
from ad_base;
Hive UDF初探的更多相关文章
- Hive UDF 实验1
项目中使用的hive版本低于0.11,无法使用hive在0.11中新加的开窗分析函数. 在项目中需要使用到row_number()函数的地方,有人写了udf来实现这个功能. new java proj ...
- hive UDF添加方式
hive UDF添加的方式 1.添加临时函数,只能在此会话中生效,退出hive自动失效 hive> add jar /home/jtdata/hiveUDF/out0.jar; Added [/ ...
- DeveloperGuide Hive UDF
Creating Custom UDFs First, you need to create a new class that extends UDF, with one or more method ...
- [转]HIVE UDF/UDAF/UDTF的Map Reduce代码框架模板
FROM : http://hugh-wangp.iteye.com/blog/1472371 自己写代码时候的利用到的模板 UDF步骤: 1.必须继承org.apache.hadoop.hive ...
- 2、Hive UDF编程实例
Hive的UDF包括3种:UDF(User-Defined Function).UDAF(User-Defined Aggregate Function)和UDTF(User-Defined Tabl ...
- Hive UDF 用户自定义函数 编程及使用
首先创建工程编写UDF 代码,示例如下: 1. 新建Maven项目 udf 本机Hadoop版本为2.7.7, Hive版本为1.2.2,所以选择对应版本的jar ,其它版本也不影响编译. 2. po ...
- Hive UDF开发-简介
Hive进行UDF开发十分简单,此处所说UDF为Temporary的function,所以需要hive版本在0.4.0以上才可以. Hive的UDF开发只需要重构UDF类的evaluate函数即可.例 ...
- 【转】HIVE UDF UDAF UDTF 区别 使用
原博文出自于:http://blog.csdn.net/longzilong216/article/details/23921235(暂时) 感谢! 自己写代码时候的利用到的模板 UDF步骤: 1 ...
- HIVE udf实例
本例中udf来自<hive编程指南>其中13章自定义函数中一个例子. 按照步骤,第一步,建立一个项目,创建 GenericUDFNvl 类. /** * 不能接受第一个参数为null的情况 ...
随机推荐
- 再谈SQL Server中日志的的作用
简介 之前我已经写了一个关于SQL Server日志的简单系列文章.本篇文章会进一步挖掘日志背后的一些概念,原理以及作用.如果您没有看过我之前的文章,请参阅: 浅谈SQL Server ...
- TaintDroid剖析之IPC级污点传播
TaintDroid剖析之IPC级污点传播 作者:简行.走位@阿里聚安全 前言 在前三篇文章中我们详细分析了TaintDroid对DVM栈帧的修改,以及它是如何在修改之后的栈帧中实现DVM变量级污点跟 ...
- Css 动画的回调
在做项目中经常会遇到使用动画的情况.以前的情况是用js写动画,利用setTimeout函数或者window.requestAnimationFrame()实现目标元素的动画效果.虽然后者解决了刷新频率 ...
- C#中自己动手创建一个Web Server(非Socket实现)
目录 介绍 Web Server在Web架构系统中的作用 Web Server与Web网站程序的交互 HTTPListener与Socket两种方式的差异 附带Demo源码概述 Demo效果截图 总结 ...
- 常用网络工具 ipconfig arp traceroute
如今的计算机是离不开网络的计算机了,因而我们对网络要有一基础的认识.连不上网,程序运行不正常之类的,多少都与网络有关.本文将介绍常用的工具. 网络出问题 ipconfig ping 网络连不上,首先要 ...
- 在职场中混,"讲演稿"的重要性
背景: 在职场上工作的人,思维都像流水行云一样无拘无束.某时某刻说不定就会产生点“头脑风暴”. 但是在多数情总下,只是自己想想,跟朋友吹瞌子的时候随便说说,很少有用文字,图形把自己的思维给表现出来. ...
- 我所理解的RESTful Web API [Web标准篇]
REST不是一个标准,而是一种软件应用架构风格.基于SOAP的Web服务采用RPC架构,如果说RPC是一种面向操作的架构风格,而REST则是一种面向资源的架构风格.REST是目前业界更为推崇的构建新一 ...
- 《Entity Framework 6 Recipes》中文翻译系列 (18) -----第三章 查询之结果集扁平化和多属性分组
翻译的初衷以及为什么选择<Entity Framework 6 Recipes>来学习,请看本系列开篇 3-14 结果集扁平化 问题 你有一对多关联的两个实体,你想通过一个查询,获取关联 ...
- mysql 的 VARCHAR VARCHAR2
mysql 里面竟然没有 VARCHAR2 ??
- 《Spark大数据处理》—— 读后总结
前几章 工作机制