package com.lwz.udaf;
import org.apache.hadoop.hive.ql.exec.UDAF;
import org.apache.hadoop.hive.ql.exec.UDAFEvaluator;
//1.此函数区分一条记录的方法,如果没有group by和where的检索,那么整个表的数据都会被作为一条数据,从而只会init()一次
//然后再把这条数据根据表里面的行数依次进行iterator(),再把iterator()方法返回的结果通过terminatePartial()返回,当再次
//进行iterator()时,结果就会累加,当最后通过terminate()返回,那么此条记录也就处理完成
//2.如果hql中有group by,那么整张表就会被分为几条记录,而且每次处理新记录前都会被init()一次,其余的每个步骤都和上一样
public class MyConcat extends UDAF {
public static class ConcatUDAFEvaluator implements UDAFEvaluator{
public static class PartialResult{
String result;
String delimiter;
}
private PartialResult partial;
//初始化每条记录
public void init() {
//每次初始化就是将partial置为空
partial = null;
}
//根据数据的行数轮转调用iterate方法
public boolean iterate(String id,String name,String deli){
if (name == null||id==null){
//如果传入的参数为空
return true;
}
if (partial == null){
//如果部分结果输出为空,说明是开始读入新的一条记录或者是第一条记录
partial = new PartialResult();
//给partial结果赋值
partial.result = new String("");
if( deli == null || deli.equals("") )
{
//如果分隔符为空或者为"",给partial赋予默认分隔符","
partial.delimiter = new String(",");
}
else
{
//如果分隔符不为空,则把传入的分隔符赋予partial的delimiter
partial.delimiter = new String(deli);
}
}
if ( partial.result.length() > 0 )
{
//如果partial的结果不为空,则在将结果加上分隔符
partial.result = partial.result.concat(partial.delimiter);
}
//将加上分隔符的结果和新传入进行整合
partial.result = partial.result.concat(name).concat(id);
return true;
}
//返回轮转的结果
public PartialResult terminatePartial(){
//将每条记录处理完的结果返回
return partial;
}
//合并terminatePartial()返回的结果
public boolean merge(PartialResult other){
if (other == null){
return true;
}
if (partial == null){
partial = new PartialResult();
partial.result = new String(other.result);
partial.delimiter = new String(other.delimiter);
}
else
{
if ( partial.result.length() > 0 )
{
partial.result = partial.result.concat(partial.delimiter);
}
partial.result = partial.result.concat(other.result);
}
return true;
}
//返回最终聚合的结果
public String terminate(){
return new String(partial.result);
}
}
}
•一下两个包是必须的import org.apache.hadoop.hive.ql.exec.UDAF和 org.apache.hadoop.hive.ql.exec.UDAFEvaluator
开发步骤
•函数类需要继承UDAF类,内部类Evaluator实UDAFEvaluator接口
•Evaluator需要实现 init、iterate、terminatePartial、merge、terminate这几个函数
a)init函数实现接口UDAFEvaluator的init函数。
b)iterate接收传入的参数,并进行内部的轮转。其返回类型为boolean。
c)terminatePartial无参数,其为iterate函数轮转结束后,返回轮转数据,terminatePartial类似于hadoop的Combiner。
d)merge接收terminatePartial的返回结果,进行数据merge操作,其返回类型为boolean。
e)terminate返回最终的聚集函数结果。
执行步骤
•执行求平均数函数的步骤
a)将java文件编译成Avg_test.jar。
b)进入hive客户端添加jar包:
hive>add jar /run/jar/Avg_test.jar。
c)创建临时函数:
hive>create temporary function avg_test 'hive.udaf.Avg';
d)查询语句:
hive>select avg_test(scores.math) from scores;
e)销毁临时函数:
hive>drop temporary function avg_test;
import org.apache.hadoop.hive.ql.exec.UDAF;
import org.apache.hadoop.hive.ql.exec.UDAFEvaluator;
//1.此函数区分一条记录的方法,如果没有group by和where的检索,那么整个表的数据都会被作为一条数据,从而只会init()一次
//然后再把这条数据根据表里面的行数依次进行iterator(),再把iterator()方法返回的结果通过terminatePartial()返回,当再次
//进行iterator()时,结果就会累加,当最后通过terminate()返回,那么此条记录也就处理完成
//2.如果hql中有group by,那么整张表就会被分为几条记录,而且每次处理新记录前都会被init()一次,其余的每个步骤都和上一样
public class MyConcat extends UDAF {
public static class ConcatUDAFEvaluator implements UDAFEvaluator{
public static class PartialResult{
String result;
String delimiter;
}
private PartialResult partial;
//初始化每条记录
public void init() {
//每次初始化就是将partial置为空
partial = null;
}
//根据数据的行数轮转调用iterate方法
public boolean iterate(String id,String name,String deli){
if (name == null||id==null){
//如果传入的参数为空
return true;
}
if (partial == null){
//如果部分结果输出为空,说明是开始读入新的一条记录或者是第一条记录
partial = new PartialResult();
//给partial结果赋值
partial.result = new String("");
if( deli == null || deli.equals("") )
{
//如果分隔符为空或者为"",给partial赋予默认分隔符","
partial.delimiter = new String(",");
}
else
{
//如果分隔符不为空,则把传入的分隔符赋予partial的delimiter
partial.delimiter = new String(deli);
}
}
if ( partial.result.length() > 0 )
{
//如果partial的结果不为空,则在将结果加上分隔符
partial.result = partial.result.concat(partial.delimiter);
}
//将加上分隔符的结果和新传入进行整合
partial.result = partial.result.concat(name).concat(id);
return true;
}
//返回轮转的结果
public PartialResult terminatePartial(){
//将每条记录处理完的结果返回
return partial;
}
//合并terminatePartial()返回的结果
public boolean merge(PartialResult other){
if (other == null){
return true;
}
if (partial == null){
partial = new PartialResult();
partial.result = new String(other.result);
partial.delimiter = new String(other.delimiter);
}
else
{
if ( partial.result.length() > 0 )
{
partial.result = partial.result.concat(partial.delimiter);
}
partial.result = partial.result.concat(other.result);
}
return true;
}
//返回最终聚合的结果
public String terminate(){
return new String(partial.result);
}
}
}
•一下两个包是必须的import org.apache.hadoop.hive.ql.exec.UDAF和 org.apache.hadoop.hive.ql.exec.UDAFEvaluator
开发步骤
•函数类需要继承UDAF类,内部类Evaluator实UDAFEvaluator接口
•Evaluator需要实现 init、iterate、terminatePartial、merge、terminate这几个函数
a)init函数实现接口UDAFEvaluator的init函数。
b)iterate接收传入的参数,并进行内部的轮转。其返回类型为boolean。
c)terminatePartial无参数,其为iterate函数轮转结束后,返回轮转数据,terminatePartial类似于hadoop的Combiner。
d)merge接收terminatePartial的返回结果,进行数据merge操作,其返回类型为boolean。
e)terminate返回最终的聚集函数结果。
执行步骤
•执行求平均数函数的步骤
a)将java文件编译成Avg_test.jar。
b)进入hive客户端添加jar包:
hive>add jar /run/jar/Avg_test.jar。
c)创建临时函数:
hive>create temporary function avg_test 'hive.udaf.Avg';
d)查询语句:
hive>select avg_test(scores.math) from scores;
e)销毁临时函数:
hive>drop temporary function avg_test;