2014-09-22 130 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