java - 如何从 Hive UDF 返回 Struct?

标签 java hadoop hive user-defined-functions

我找不到有关如何使用 Hive UDF 返回结构的文档。

我的主要问题是:

在 Java 中我从什么类型的对象开始?

如何转换它们以便将它们解释为 Hive 中的结构?

最佳答案

这是此类 UDF 的一个非常简单的示例。 它接收一个 User-Agent 字符串,使用外部库解析它并返回一个包含 4 个文本字段的结构:

STRUCT<类型:字符串,操作系统:字符串,系列:字符串,设备:字符串>

您需要扩展GenericUDF 类并覆盖两个最重要的方法:initializeevaluate

initialize() 描述结构本身并定义内部的数据类型。

evaluate() 用实际值填充结构。

你不需要任何特殊的类来返回,Hive 中的 struct<> 只是 Java 中的一个对象数组。

import java.util.ArrayList;
import org.apache.hadoop.hive.ql.exec.UDFArgumentException;
import org.apache.hadoop.hive.ql.metadata.HiveException;
import org.apache.hadoop.hive.ql.udf.generic.GenericUDF;
import org.apache.hadoop.hive.serde2.objectinspector.ObjectInspector;
import org.apache.hadoop.hive.serde2.objectinspector.ObjectInspectorFactory;
import org.apache.hadoop.hive.serde2.objectinspector.StructObjectInspector;
import org.apache.hadoop.hive.serde2.objectinspector.primitive.PrimitiveObjectInspectorFactory;
import org.apache.hadoop.io.Text;

import eu.bitwalker.useragentutils.UserAgent;

public class UAStructUDF extends GenericUDF {

    private Object[] result;

    @Override
    public String getDisplayString(String[] arg0) {
        return "My display string";
    }

    @Override
    public ObjectInspector initialize(ObjectInspector[] arg0) throws UDFArgumentException {
        // Define the field names for the struct<> and their types
        ArrayList<String> structFieldNames = new ArrayList<String>();
        ArrayList<ObjectInspector> structFieldObjectInspectors = new ArrayList<ObjectInspector>();

        // fill struct field names
        // type
        structFieldNames.add("type");
        structFieldObjectInspectors.add(PrimitiveObjectInspectorFactory.writableStringObjectInspector);
        //family
        structFieldNames.add("family");
        structFieldObjectInspectors.add(PrimitiveObjectInspectorFactory.writableStringObjectInspector);
        // OS name
        structFieldNames.add("os");
        structFieldObjectInspectors.add(PrimitiveObjectInspectorFactory.writableStringObjectInspector);
        // device
        structFieldNames.add("device");
        structFieldObjectInspectors.add(PrimitiveObjectInspectorFactory.writableStringObjectInspector);

        StructObjectInspector si = ObjectInspectorFactory.getStandardStructObjectInspector(structFieldNames,
                structFieldObjectInspectors);
        return si;
    }

    @Override
    public Object evaluate(DeferredObject[] args) throws HiveException {
        if (args == null || args.length < 1) {
            throw new HiveException("args is empty");
        }
        if (args[0].get() == null) {
            throw new HiveException("args contains null instead of object");
        }

        Object argObj = args[0].get();

        // get argument
        String argument = null;     
        if (argObj instanceof Text){
            argument = ((Text) argObj).toString();
        } else if (argObj instanceof String){
            argument = (String) argObj;
        } else {
            throw new HiveException("Argument is neither a Text nor String, it is a " + argObj.getClass().getCanonicalName());
        }
        // parse UA string and return struct, which is just an array of objects: Object[] 
        return parseUAString(argument);
    }

    private Object parseUAString(String argument) {
        result = new Object[4];
        UserAgent ua = new UserAgent(argument);
        result[0] = new Text(ua.getBrowser().getBrowserType().getName());
        result[1] = new Text(ua.getBrowser().getGroup().getName());
        result[2] = new Text(ua.getOperatingSystem().getName());
        result[3] = new Text(ua.getOperatingSystem().getDeviceType().getName());
        return result;
    }
}

关于java - 如何从 Hive UDF 返回 Struct?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26026027/

相关文章:

java - 使用jxl为excel表中的单元格设置不同的颜色

java - Java中两个字节数组的绝对值减法

hadoop - 如何将HiveQL查询的结果输出到逗号分隔或管道分隔的文件?

hadoop - 如何使用 ORC 存储 Hive 表以进行复杂查询?

sorting - Hive 不区分大小写的字母排序

java - java中终止一个线程有一点问题

java - 如何获得不可修改的 LinkedHashSet

mysql - Hadoop 与关系数据库

java - 使用 Map Reduce 的最小最大计数

mysql - 编译语句 : FAILED: SemanticException [Error 10036]: Duplicate column name: p_id 时出错