傻大方


首页 > 潮·科技 > >

hive学习笔记之十一:UDTF( 二 )



按关键词阅读:

inputFields = argOIs.getAllStructFieldRefs();// 当前UDTF只处理一个参数 , 在此判断传入的是不是一个参数if (1 != inputFields.size()) {throw new UDFArgumentLengthException("ExplodeMap takes only one argument");}// 此UDTF只处理字符串类型if(!Category.PRIMITIVE.equals(inputFields.get(0).getFieldObjectInspector().getCategory())) {throw new UDFArgumentException("ExplodeMap takes string as a parameter");}stringOI = (PrimitiveObjectInspector)inputFields.get(0).getFieldObjectInspector();//列名集合ArrayList fieldNames = new ArrayList();//列对应的value值ArrayList fieldOIs = new ArrayList();// 第一列的列名fieldNames.add("id");// 第一列的inspector类型为string型fieldOIs.add(PrimitiveObjectInspectorFactory.javaStringObjectInspector);// 第二列的列名fieldNames.add("key");// 第二列的inspector类型为string型fieldOIs.add(PrimitiveObjectInspectorFactory.javaStringObjectInspector);// 第三列的列名fieldNames.add("value");// 第三列的inspector类型为string型fieldOIs.add(PrimitiveObjectInspectorFactory.javaStringObjectInspector);return ObjectInspectorFactory.getStandardStructObjectInspector(fieldNames, fieldOIs);}}

  • 上述代码中的重点是process方法 , 取得入参后用冒号分割字符串 , 得到数组 , 再调用forward方法 , 就生成了一行记录 , 该记录有三列:id、key、value;
验证UDTF接下来将WordSplitSingleRow.java部署成临时函数并验证;
  1. 编码完成后 , 在pom.xml所在目录执行命令mvn clean package -U;
  2. 在target目录得到文件hiveudf-1.0-SNAPSHOT.jar
  3. 将jar下载到hive服务器 , 我这里放在此目录:/home/hadoop/udf/
  4. 在hive会话模式执行以下命令添加本地jar:
add jar /home/hadoop/udf/hiveudf-1.0-SNAPSHOT.jar;
  1. 部署临时函数:
create temporary function udf_wordsplitsinglerow as 'com.bolingcavalry.hiveudf.udtf.WordSplitSingleRow';
  1. 执行以下SQL验证:
select udf_wordsplitsinglerow(string_field) from t16;
  1. 结果如下 , 可见每一行记录的string_field字段都被分割成了id、key、value三个字段:
hive> select udf_wordsplitsinglerow(string_field) from t16;OKid key value1 province guangdong2 city shenzhen3 can not split to valid array -Time taken: 0.066 seconds, Fetched: 3 row(s)关键点要注意
  • 值得注意的是 , UDTF不能和其他字段同时出现在select语句中 , 例如以下的SQL会执行失败:
select person_name,udf_wordsplitsinglerow(string_field) from t16;
  • 错误信息如下:
hive> select person_name,udf_wordsplitsinglerow(string_field) from t16;FAILED: SemanticException [Error 10081]: UDTF's are not supported outside the SELECT clause, nor nested in expressions
  • 如果希望同时得到UDTF和其他字段的结果 , 可以使用LATERAL VIEW语法 , 完整SQL如下:
select t.person_name, udtf_id, udtf_key, udtf_valuefrom (select person_name, string_fieldfromt16) t LATERAL VIEW udf_wordsplitsinglerow(t.string_field) v asudtf_id, udtf_key, udtf_value;
  • 查询结果如下 , 可见指定字段和UDTF都能显示:
hive> select t.person_name, udtf_id, udtf_key, udtf_value> from (>select person_name, string_field>fromt16> ) t LATERAL VIEW udf_wordsplitsinglerow(t.string_field) v asudtf_id, udtf_key, udtf_value;OKt.person_name udtf_id udtf_key udtf_valuetom 1 province guangdongjerry 2 city shenzhenjohn 3 can not split to valid array -Time taken: 0.122 seconds, Fetched: 3 row(s)一列拆成多行(每行多列)
  • 前面咱们试过了将string_field字段拆分成id、key、value三个字段 , 不过拆分后总行数还是不变 , 接下来的UDTF名为udf_wordsplitmultirow , 是把string_field拆分成多条记录 , 然后每条记录都有三个字段;
  • 需要导入新的数据到t16表 , 新建文本文件016_multi.txt , 内容如下:
tom|1:province:guangdong,4:city:yangjiangjerry|2:city:shenzhenjohn|3
  • 在hive会话窗口执行以下命令 , 会用016_multi.txt的内容覆盖t16表已有内容:
load data local inpath '/home/hadoop/temp/202010/25/016_multi.txt' overwrite into table t16;
  • 此时的数据如下图所示 , 红框中是一条记录的string_field字段值 , 咱们接下来要开发的UDTF , 会先用逗号分隔 , 得到的就是1:province:guangdong和4:city:yangjiang这两个字符串 , 接下来对每个字符串用冒号分隔 , 就会得到两条id、key、value这样的记录 , 也就是多行多列:
hive学习笔记之十一:UDTF文章插图
  • 预期中的UDTF结果如下图所示 , 红框和黄框这两条记录都来自一条记录的string_field字段值:


    稿源:(未知)

    【傻大方】网址:http://www.shadafang.com/c/111J2D952020.html

    标题:hive学习笔记之十一:UDTF( 二 )


上一篇:不标配充电头?iPhone12用户的自我救赎,我的解决方案是

下一篇:iPhone12mini开售,价格较少800元,但差距很明显