从单个Hive UDF创建多个列

我正在使用Amazon EMR和Hive 0.11。 我正在尝试创建一个Hive UDF,它将从一个UDF调用返回多个列。

例如,我想调用类似下面的UDF并返回几个(命名)列。

SELECT get_data(columnname) FROM table; 

我无法找到完成此操作的文档,但是如果使用Generic UDF,则可以听到。 有谁知道需要从evaluate()方法返回什么才能工作?

我只是使用GenericUDTF。在编写了GenericUDTF的udf扩展后,你的udtf应该实现两个重要的方法:初始化和评估。

  • 在初始化中,您可以检查参数类型并设置返回对象类型。 例如,使用ObjectInspectorFactory.getStandardStructObjectInspector,您可以使用structFieldNames参数的名称和structFieldObjectInspectors中的列值类型指定输出列。 输出列大小是structFieldNames列表的大小。 有两种类型系统:java和hadoop。 java的ObjectInspector是带有javaXXObjectInspector的begein,否则它以writableXXObjectInspector开头。
  • 在过程中,它类似于常见的udf。 除此之外,您应该使用从initialize()保存的ObjectInspector将Object转换为具体值,如String,Integer等。前转函数输出一行。 在行对象forwardColObj中,您可以指定列对象。

以下是一个简单的例子:


 public class UDFExtractDomainMethod extends GenericUDTF { private static final Integer OUT_COLS = 2; //the output columns size private transient Object forwardColObj[] = new Object[OUT_COLS]; private transient ObjectInspector[] inputOIs; /** * * @param argOIs check the argument is valid. * @return the output column structure. * @throws UDFArgumentException */ @Override public StructObjectInspector initialize(ObjectInspector[] argOIs) throws UDFArgumentException { if (argOIs.length != 1 || argOIs[0].getCategory() != ObjectInspector.Category.PRIMITIVE || !argOIs[0].getTypeName().equals(serdeConstants.STRING_TYPE_NAME)) { throw new UDFArgumentException("split_url only take one argument with type of string"); } inputOIs = argOIs; List outFieldNames = new ArrayList(); List outFieldOIs = new ArrayList(); outFieldNames.add("host"); outFieldNames.add("method"); outFieldOIs.add(PrimitiveObjectInspectorFactory.javaStringObjectInspector); //writableStringObjectInspector correspond to hadoop.io.Text outFieldOIs.add(PrimitiveObjectInspectorFactory.javaStringObjectInspector); return ObjectInspectorFactory.getStandardStructObjectInspector(outFieldNames, outFieldOIs); } @Override public void process(Object[] objects) throws HiveException { try { //need OI to convert data type to get java type String inUrl = ((StringObjectInspector)inputOIs[0]).getPrimitiveJavaObject(objects[0]); URI uri = new URI(inUrl); forwardColObj[0] = uri.getHost(); forwardColObj[1] = uri.getRawPath(); //output a row with two column forward(forwardColObj); } catch (URISyntaxException e) { e.printStackTrace(); } } @Override public void close() throws HiveException { } }