2014-09-22 323 views
4

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

例如,我想调用一个如下所示的UDF并返回几个(命名)列。

SELECT get_data(columnname) FROM table; 

我很难找到正在完成的文档,但是听说如果使用通用UDF就有可能。有没有人知道需要从evaluate()方法中返回什么才能工作?

+0

这是如何从表'选择列名不同;'? – gobrewers14 2014-09-25 22:33:20

回答

3

我只是使用GenericUDTF.After你写了一个udf扩展的GenericUDTF,你的udtf应该实现两个重要的方法:initialize和evaluate。

  • 在初始化中,您可以检查参数类型并设置返回对象类型。 例如,使用ObjectInspectorFactory.getStandardStructObjectInspector,可以使用structFieldNames参数的名称和structFieldObjectInspectors中的列值类型来指定输出列。输出列大小是structFieldNames列表的大小。 有两种类型的系统:java和hadoop。 java的ObjectInspector与javaXXObjectInspector是begein,否则它以writableXXObjectInspector开头。
  • 在过程中,它与常见的udf类似。除此之外,您应该使用从initialize()保存的ObjectInspector将Object转换为具体值,例如String,Integer等。调用​​forward函数输出一行。在行对象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<String> outFieldNames = new ArrayList<String>(); 
     List<ObjectInspector> outFieldOIs = new ArrayList<ObjectInspector>(); 
     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 { 

    } 
} 
+0

请给你的代码添加一些解释。 – 2015-02-01 13:11:21