我无法找到有关如何使用Hive UDF返回结构的文档。如何从Hive UDF返回Struct?
我的主要问题是:
我在Java中使用哪些类型的对象?
我该如何转换它们才能将它们解释为Hive中的Struct?
我无法找到有关如何使用Hive UDF返回结构的文档。如何从Hive UDF返回Struct?
我的主要问题是:
我在Java中使用哪些类型的对象?
我该如何转换它们才能将它们解释为Hive中的Struct?
HIVE中有一个SerDe(串行器和解串器)的概念,可以与您正在播放的数据格式一起使用。它序列化对象(复杂),然后根据需要对其进行反序列化。例如,如果您有一个包含对象和值的JSON文件,那么您需要一种将这些内容存储在配置单元中的方法。 为此,我们使用JsonSerde,它实际上是一个jar文件,它包含用java编写的用于与Json数据一起玩的解析器代码。
所以你现在有一个jar(SerDe),另一个需求是模式存储这些数据。 对于例如:对于XML文件,您需要XSD, 类似地为JSON定义对象,数组和结构关系。 您可以检查此链接: http://thornydev.blogspot.in/2013/07/querying-json-records-via-hive.html 请让我知道如果这有助于解决了你的目的:)
这里是这类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;
}
}