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初探的更多相关文章

  1. Hive UDF 实验1

    项目中使用的hive版本低于0.11,无法使用hive在0.11中新加的开窗分析函数. 在项目中需要使用到row_number()函数的地方,有人写了udf来实现这个功能. new java proj ...

  2. hive UDF添加方式

    hive UDF添加的方式 1.添加临时函数,只能在此会话中生效,退出hive自动失效 hive> add jar /home/jtdata/hiveUDF/out0.jar; Added [/ ...

  3. DeveloperGuide Hive UDF

    Creating Custom UDFs First, you need to create a new class that extends UDF, with one or more method ...

  4. [转]HIVE UDF/UDAF/UDTF的Map Reduce代码框架模板

    FROM : http://hugh-wangp.iteye.com/blog/1472371 自己写代码时候的利用到的模板   UDF步骤: 1.必须继承org.apache.hadoop.hive ...

  5. 2、Hive UDF编程实例

    Hive的UDF包括3种:UDF(User-Defined Function).UDAF(User-Defined Aggregate Function)和UDTF(User-Defined Tabl ...

  6. Hive UDF 用户自定义函数 编程及使用

    首先创建工程编写UDF 代码,示例如下: 1. 新建Maven项目 udf 本机Hadoop版本为2.7.7, Hive版本为1.2.2,所以选择对应版本的jar ,其它版本也不影响编译. 2. po ...

  7. Hive UDF开发-简介

    Hive进行UDF开发十分简单,此处所说UDF为Temporary的function,所以需要hive版本在0.4.0以上才可以. Hive的UDF开发只需要重构UDF类的evaluate函数即可.例 ...

  8. 【转】HIVE UDF UDAF UDTF 区别 使用

    原博文出自于:http://blog.csdn.net/longzilong216/article/details/23921235(暂时) 感谢! 自己写代码时候的利用到的模板   UDF步骤: 1 ...

  9. HIVE udf实例

    本例中udf来自<hive编程指南>其中13章自定义函数中一个例子. 按照步骤,第一步,建立一个项目,创建 GenericUDFNvl 类. /** * 不能接受第一个参数为null的情况 ...

随机推荐

  1. C ReadProcessMemory

    ReadProcessMemory函数用于读取其他进程的数据. BOOL STDCALL ReadProcessMemory ( HANDLE hProcess, LPCVOID lpBaseAddr ...

  2. 用Fmx调用Bass.dll

    先上图 帮亲戚做个小软件,选用FMX,因为画面不会像vcl那样在图片多的时候闪烁.还能添加动画 但是MediaPlayer播放音乐视频真是不给力,视频没想到好办法.音频方面想到之前万一的Bass.ll ...

  3. 《Linux内核设计与实现》读书笔记 第十八章 调试

    第十八章调试 18.1 准备开始          需要准备的东西: l  一个bug:大部分bug通常都不是行为可靠而且定义明确的 l  一个藏匿bug的内核版本:找出bug首先出现的版本 l  相 ...

  4. ABP理论学习之工作单元(Unit of Work)

    返回总目录 本篇目录 公共连接和事务管理方法 ABP中的连接和事务管理 仓储类 应用服务 工作单元 工作单元详解 关闭工作单元 非事务的工作单元 工作单元方法调用其它 工作单元作用域 自动保存 IRe ...

  5. .Net中的反应式编程(Reactive Programming)

    系列主题:基于消息的软件架构模型演变 一.反应式编程(Reactive Programming) 1.什么是反应式编程:反应式编程(Reactive programming)简称Rx,他是一个使用LI ...

  6. Python黑帽编程1.1虚拟机安装和配置 Kali Linux 2016

    Python黑帽编程1.1虚拟机安装和配置 Kali Linux 2016 0.1  本系列教程说明 本系列教程,采用的大纲母本为<Understanding Network Hacks Att ...

  7. window系统JDK1.7的快速配置

    快速配置java环境变量 右键单击计算机--->属性 点击 "高级系统设置"--->"环境变量",出现环境变量设置窗口 系统变量--->新建 ...

  8. 拓展 Android 原生 CountDownTimer 倒计时

    拓展 Android 原生 CountDownTimer 倒计时 [TOC] CountDownTimer 在系统的CountDownTimer上进行的修改,主要是拓展了功能,当然也保留了系统默认的模 ...

  9. java 成长之路

    分享总结 title: java 成长之路 tags: grammar_cjkRuby: true 经验差异 1-3年 要求 建议 3-5年 建议 5年+ 经验差异 最近一年比较忙,经历了创业公司的倒 ...

  10. ModelDataExchange - Import

    ModelDataExchange - Import eryar@163.com Abstract. The ModelDataExchange import utility enables the ...