Hive 自定义函数
Hive 自带了一些函数,比如:max/min等,但是数量有限,自己可以通过自定义UDF来方便的扩展。当Hive提供的内置函数无法满足你的业务处理需要时,此时就可以考虑使用用户自定义函数(UDF:user-defined function)官方参考 https://cwiki.apache.org/confluence/display/Hive/HivePlugins
接下来,通过两个自定义函数来看看怎么进行自定义函数;
1、引入依赖编写代码
<dependencies> <dependency> <groupId>org.apache.hive</groupId> <artifactId>hive-exec</artifactId> <version>3.1.2</version> </dependency> </dependencies>
编写 UDF 逻辑
/** * 自定义实现 length() 函数 */ public class MyStringLength extends GenericUDF { /** * @param arguments 输入参数类型的鉴别器对象 * @return 返回值类型鉴别器对象 * @throws UDFArgumentException */ public ObjectInspector initialize(ObjectInspector[] arguments) throws UDFArgumentException { //判断输入参数个数 if (arguments.length != 1) { throw new UDFArgumentLengthException("Input args length Error..."); } //判断输入参数类型 if (!arguments[0].getCategory().equals(ObjectInspector.Category.PRIMITIVE)) { throw new UDFArgumentTypeException(0, "Input Args Type Error..."); } //函数本身返回值 int,需要返回 int 类型的鉴别器对象 return PrimitiveObjectInspectorFactory.javaIntObjectInspector; } /** * 函数处理逻辑 * * @param arguments 输入参数 * @return 返回值 * @throws HiveException */ public Object evaluate(DeferredObject[] arguments) throws HiveException { if (arguments[0].get() == null) { return 0; } return arguments[0].get().toString().length(); } public String getDisplayString(String[] strings) { return ""; } }
编写UDTF
/** * 自定义 udtf 函数 */ public class MyUDTF extends GenericUDTF { private ArrayList<String> outList = new ArrayList<String>(); @Override public StructObjectInspector initialize(StructObjectInspector argOIs) throws UDFArgumentException { //定义输出数据的列名和类型 ArrayList<String> fieldNames = new ArrayList<String>(); ArrayList<ObjectInspector> fieldOis = new ArrayList<ObjectInspector>(); //添加输出数据的列名和类型 fieldNames.add("LineToWorld"); fieldOis.add(PrimitiveObjectInspectorFactory.javaStringObjectInspector); return ObjectInspectorFactory.getStandardStructObjectInspector(fieldNames, fieldOis); } public void process(Object[] args) throws HiveException { //1、获取原始数据 String arg = args[0].toString(); //2、获取数据传入的第二个参数,此处为分隔符 String splity = args[1].toString(); //3、将原始数据按照传入的分隔符进行切分 String[] fileds = arg.split(splity); //4、遍历切分后的结果,并写出 for (String filed : fileds) { //集合复用,清空集合 outList.clear(); //将每一个单词添加到集合 outList.add(filed); //写出集合内容 forward(outList); } } public void close() throws HiveException { } }
打包后上传到 hdfs
上传到 jar 文件 hdfs
[hui@hadoop201 data]$ hadoop fs -put myhivefunc.jar /hivefun
2、创建函数并使用
创建字符串长度函数
create function mylen as 'org.wdh01.hive.fun.MyStringLength' using jar 'hdfs://hadoop201//hivefun/myhivefunc.jar';
使用
select mylen("123"),mylen("hello hive") 3 10
创建分词函数
create function mysplit as 'org.wdh01.hive.fun.MyUDTF' using jar 'hdfs://hadoop201//hivefun/myhivefunc.jar';
使用
select mysplit("hello,world,hadoop,hive",","); hello world hadoop hive