Hive自定义UDF函数

目录

一、UDF概述

UDF全称:User-Defined Functions,即用户自定义函数,在Hive SQL编译成MapReduce任务时,执行java方法,类似于像MapReduce执行过程中加入一个插件,方便扩展。

二、UDF种类

UDF:操作单个数据行,产生单个数据行;

UDAF:操作多个数据行,产生一个数据行;

UDTF:操作一个数据行,产生多个数据行一个表作为输出;

三、如何自定义UDF

1.编写UDF函数,UDF需要继承org.apache.hadoop.hive.ql.exec.UDF,UDTF继承org.apache.hadoop.hive.ql.udf.generic.GenericUDTF,UDAF使用比较少,这里先不讲解;

2.将写好的类打包为jar,如HiveUDF-1.0.jar,并且上传到Hive机器或者HDFS目录

3.入到Hive shell环境中,输入命令add jar /home/hadoop/HiveUDF-1.0.jar注册该jar文件;或者把HiveUDF-1.0.jar上传到hdfs,hadoop fs -put HiveUDF-1.0.jar /home/hadoop/HiveUDF-1.0.jar,再输入命令add jar hdfs://hadoop60:8020/home/hadoop/HiveUDF-1.0.jar;

4.为UDF类起一个别名,create temporary function myudf as 'com.master.HiveUDF.MyUDF';注意,这里UDF只是为这个Hive会话临时定义的;

5.在select中使用myudf();

四、自定义实现UDF和UDTF

Hive中解析复杂JSON数据的方法,通过自定义UDF函数GetJsonObject和GetJsonArray,实现了对JSON对象和数组的有效解析。

pom.xml配置信息

java 复制代码
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>org.example</groupId>
    <artifactId>json_array</artifactId>
    <version>1.0-SNAPSHOT</version>
    <dependencies>
        <dependency>
            <groupId>org.apache.hive</groupId>
            <artifactId>hive-exec</artifactId>
            <version>3.1.2</version>
        </dependency>
    </dependencies>
</project>

一、JSONObject解析JSON对象

java 复制代码
package com.jd.bdp.util.udf;
import org.apache.commons.lang.StringUtils;
import org.apache.hadoop.hive.ql.exec.UDF;
import org.json.JSONException;
import org.json.JSONObject;
import org.json.JSONTokener;
/**
 * JSON对象解析UDF
 * date:2017-04-20
 */
public class GetJsonObject extends UDF {
    /**
     * 解析json并返回对应的值。例如
     add jar jar/bdp_udf_demo-1.0.0.jar;
     create temporary function getJsonObject as 'com.jd.bdp.util.udf.GetJsonObject';
     select getJsonObject(json字符串,key值)
     * @param jsonStr
     * @param objName
     * @return
     */
    public String evaluate(String jsonStr,String objName) throws JSONException {
        if(StringUtils.isBlank(jsonStr)|| StringUtils.isBlank(objName)){
            return null;
        }
        JSONObject jsonObject = new JSONObject(new JSONTokener(jsonStr));
        Object objValue = jsonObject.get(objName);
        if(objValue==null){
            return null;
        }
        return objValue.toString();
    }
}

二、JSONArray解析JSON数组对象

java 复制代码
package com.jd.bdp.util.udf;
import org.apache.commons.lang.StringUtils;
import org.apache.hadoop.hive.ql.exec.UDF;
import org.apache.hadoop.hive.ql.metadata.HiveException;
import org.apache.hadoop.io.Text;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONTokener;
import java.util.ArrayList;
/**
 * JSON数组对象解析UDF
 * date:2017-04-20
 */
public class GetJsonArray extends UDF {
    /**
     * 解析json并返回对应子json字符串数组,例如
     add jar jar/bdp_udf_demo-1.0.0.jar;
     create temporary function getJsonArray as 'com.jd.bdp.util.udf.GetJsonArray';
     select getJsonArray(json字符串)
     * @param jsonArrayStr
     * @return
     * @throws HiveException
     */
    public ArrayList<Text> evaluate(String jsonArrayStr) throws JSONException {
        if(StringUtils.isBlank(jsonArrayStr)||StringUtils.isBlank(jsonArrayStr)){
            return null;
        }
        ArrayList<Text> textList = new ArrayList<Text>();
        if(!jsonArrayStr.trim().startsWith("[")){
            textList.add(new Text(jsonArrayStr));
        }else{
            JSONArray jsonArray = new JSONArray(new JSONTokener(jsonArrayStr));
            Text[] jsonTexts = new Text[jsonArray.length()];
            for(int i=0;i<jsonArray.length();i++){
                String json = jsonArray.getJSONObject(i).toString();
                textList.add(new Text(json));
            }
        }
        return textList;
    }
}

三、两个UDF的配合使用过程

添加自定义函数

sql 复制代码
add jar jar/bdp_udf_demo-1.0.0.jar;
create temporary function getJsonObject as 'com.jd.bdp.util.udf.GetJsonObject';
create temporary function getJsonArray as 'com.jd.bdp.util.udf.GetJsonArray';

在hql中使用自定义UDF函数

本场景是对temp1表中的productioninfo中json字符串数组解析,并使用lateral view explode对生成的子json字符串数组列转行,最后对子json字符串解析读取数据。

sql 复制代码
select 
        getJsonObject(adtable.info,'factoryAddress') factoryAddress,
        getJsonObject(adtable.info,'factoryName') factoryName,
        getJsonObject(adtable.info,'factoryQs') factoryQs,
        *
from
(
        select * from temp1 where dp = 'ACTIVE'
)dtl lateral view explode(getJsonArray(productioninfo)) adtable as info 
相关推荐
core5123 天前
Hive实战(三)
数据仓库·hive·hadoop
程序员小羊!4 天前
大数据电商流量分析项目实战:Hive 数据仓库(三)
大数据·数据仓库·hive
core5124 天前
Hive实战(一)
数据仓库·hive·hadoop·架构·实战·配置·场景
智海观潮4 天前
Spark SQL解析查询parquet格式Hive表获取分区字段和查询条件
hive·sql·spark
cxr8285 天前
基于Claude Code的 规范驱动开发(SDD)指南
人工智能·hive·驱动开发·敏捷流程·智能体
core5126 天前
Hive实战(二)
数据仓库·hive·hadoop
Agatha方艺璇6 天前
Hive基础简介
数据仓库·hive·hadoop
像豆芽一样优秀8 天前
Hive和Flink数据倾斜问题
大数据·数据仓库·hive·hadoop·flink
howard20058 天前
VMWare上搭建Hive集群
hive·hadoop
程序猿 董班长10 天前
springboot配置多数据源(mysql、hive)
hive·spring boot·mysql