如何从hiveudf返回struct?

f1tvaqid  于 2021-06-02  发布在  Hadoop
关注(0)|答案(2)|浏览(479)

我找不到有关如何使用配置单元自定义项返回结构的文档。
我的主要问题是:
在java中,我应该从什么类型的对象开始?
如何将它们转换为配置单元中的结构?

yruzcnhs

yruzcnhs1#

下面是一个非常简单的例子。它接收一个用户代理字符串,使用外部lib对其进行解析,并返回一个包含4个文本字段的结构:
结构type:string,os:string,family:string,device:string
您需要扩展genericudf类并重写两个最重要的方法:initialize和evaluate。
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;
    }
}
2sbarzqh

2sbarzqh2#

在配置单元中有一个serde(序列化程序和反序列化程序)的概念,可以与正在播放的数据格式一起使用。它序列化对象(复杂),然后根据需要反序列化。例如,如果您有一个包含对象和值的json文件,那么您需要一种方法将该内容存储在配置单元中。为此,您将使用一个jsonserde,它实际上是一个jar文件,包含用java编写的用于处理json数据的解析器代码。
现在您有了一个jar(serde),另一个要求是使用一个模式来存储该数据。例如:对于xml文件,需要xsd,对于json,同样需要定义对象、数组和结构关系。您可以检查此链接:http://thornydev.blogspot.in/2013/07/querying-json-records-via-hive.html 请让我知道这是否有助于解决您的目的:)

相关问题