2014-09-24 113 views
1

我无法找到有关如何使用Hive UDF返回结构的文档。如何从Hive UDF返回Struct?

我的主要问题是:

我在Java中使用哪些类型的对象?

我该如何转换它们才能将它们解释为Hive中的Struct?

回答

0

HIVE中有一个SerDe(串行器和解串器)的概念,可以与您正在播放的数据格式一起使用。它序列化对象(复杂),然后根据需要对其进行反序列化。例如,如果您有一个包含对象和值的JSON文件,那么您需要一种将这些内容存储在配置单元中的方法。 为此,我们使用JsonSerde,它实际上是一个jar文件,它包含用java编写的用于与Json数据一起玩的解析器代码。

所以你现在有一个jar(SerDe),另一个需求是模式存储这些数据。 对于例如:对于XML文件,您需要XSD, 类似地为JSON定义对象,数组和结构关系。 您可以检查此链接: http://thornydev.blogspot.in/2013/07/querying-json-records-via-hive.html 请让我知道如果这有助于解决了你的目的:)

2

这里是这类UDF的一个很简单的例子。 它接收一个用户代理字符串,使用外部的lib解析它,并返回一个结构4个文本字段:

STRUCT <类型:字符串,OS:串,家族:串,设备:串>

您需要扩展GenericUDF类并覆盖两个最重要的方法:初始化评估

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; 
    } 
}