UDF函数

  HIVE允许用户使用UDF(User Defined Function)用户自定义函数,对函数功能进行扩展,处理数据。

UDF(一对一)

  1、UDF:用户定义(普通)函数,只对单行数值产生作用。
  继承UDF类,添加方法 evaluate()。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public class Min extends UDF {

public Double evaluate(Double a, Double b) {

if (a == null)
a = 0.0;
if (b == null)
b = 0.0;
if (a >= b) {
return b;
} else {
return a;
}
}
}

UDAF(多对一)

  UDAF:User Defined Aggregation Funcation。
  用户定义聚合函数,可对多行数据产生作用;等同于SQL中常用的SUM(),AVG(),也是聚合函数。
  聚合函数使用:  

1
2
3
4
5
SELECT store_name, SUM(sales) 
FROM Store_Information
GROUP BY store_name
HAVING SUM(sales) > 1500
ORDER BY SUM(sales);

  键字HAVING总要放在GROUP BY之后,ORDER BY之前
  UDAF实现有简单与通用两种方式:
  a. 简单UDAF因为使用Java反射导致性能损失,而且有些特性不能使用,已经被弃用了;

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
import org.apache.hadoop.hive.ql.exec.UDAF;
import org.apache.hadoop.hive.ql.exec.UDAFEvaluator;
import org.apache.hadoop.io.IntWritable;

//UDAF是输入多个数据行,产生一个数据行
//用户自定义的UDAF必须是继承了UDAF,且内部包含多个实现了exec的静态类
public class MaxiNumber extends UDAF {
public static class MaxiNumberIntUDAFEvaluator implements UDAFEvaluator {
// 最终结果
private IntWritable result;

// 负责初始化计算函数并设置它的内部状态,result是存放最终结果的
@Override
public void init() {
result = null;
}

// 每次对一个新值进行聚集计算都会调用iterate方法
public boolean iterate(IntWritable value) {
if (value == null)
return false;
if (result == null)
result = new IntWritable(value.get());
else
result.set(Math.max(result.get(), value.get()));
return true;
}

// Hive需要部分聚集结果的时候会调用该方法
// 会返回一个封装了聚集计算当前状态的对象
public IntWritable terminatePartial() {
return result;
}

// 合并两个部分聚集值会调用这个方法
public boolean merge(IntWritable other) {
return iterate(other);
}

// Hive需要最终聚集结果时候会调用该方法
public IntWritable terminate() {
return result;
}
}
}

b. 另一种涉及两个类:AbstractGenericUDAFResolver、GenericUDAFEvaluator;
  继承UDAFResolver类,重写 getEvaluator() 方法;
  继承GenericUDAFEvaluator类,生成实例给getEvaluator();
  在GenericUDAFEvaluator类中,重写init()、iterate()、terminatePartial()、merge()、terminate()方法;

UDTF(一对多)

  UDTF:User-Defined Table-Generating Functions。
  用户定义表生成函数,用来解决输入一行输出多行。
  继承GenericUDTF类,重写initialize(返回输出行信息:列个数,类型), process, close三方法;