hive自定义udf和udaf
-
自定义udf
继承UDF类,在类里面自定定义evaluate方法,参数和返回值都是自己定义,同时一个自定义udf中可以定义多个重载的evaluate方法,根据传入参数的个数和类型来自动调用对应的evaluate方法。
package whut; import org.apache.commons.lang.StringUtils; import org.apache.hadoop.hive.ql.exec.UDF; import org.apache.hadoop.io.Text; //UDF是作用于单个数据行,产生一个数据行 //用户必须要继承UDF,且必须至少实现一个evalute方法,该方法并不在UDF中 //但是Hive会检查用户的UDF是否拥有一个evalute方法 public class Strip extends UDF{ private Text result=new Text(); //自定义方法 public Text evaluate(Text str) { if(str==null) return null; result.set(StringUtils.strip(str.toString())); return result; } public Text evaluate(Text str,String stripChars) { if(str==null) return null; result.set(StringUtils.strip(str.toString(),stripChars)); return result; }
-
自定义udaf
继承UDAF类,同时内部必须定义一个静态类实现UDAFEvaluator类
init方法,初始化内部的初始值
iterate()对新值进行聚合计算
terminatePartial 需要部分聚集结果的时候会调用该方法,会返回一个封装了聚集计算的当前状态
merge(IntWritable other) 合并两个部分聚集结果
terminate() 返回最终聚合结果
该UDAF主要是找到最大值 package whut; 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; } }
hive创建函数的方式
-
创建临时的函数,仅对当前sessioin有效。在hive的交互窗口中使用
add jar hdfs://my_udf.jar
create tempory function myUdf as 'com.×.×.MyUDF'
drop tempory function if exists MyUdf
-
创建永久性函数
先将jar包放到hdfs
create function dbName.function_name as 'com.×.×.MyUDF' using jar 'hdfs://....jar'
使用udf的场景
一级分类。
对于逗号分隔的字符串,分隔之后其实是一个列表。如果分隔有重复的元素需要进行去重。
如果不使用udf的操作就是先split分隔再做explode的爆炸处理成多行,再进行聚合的collect_set操作。
自定义了一个udf直接对逗号分隔的字符串中进行去重。
使用hive自定义udf对imei号进行脱敏操作。
日期格式的转换
query中badChar特殊字符的清洗
等