2014-09-22 4 views
4

Я использую Amazon EMR и Hive 0.11. Я пытаюсь создать UUF Hive, который будет возвращать несколько столбцов из одного вызова UDF.Создание нескольких столбцов из одного Hive UDF

Например, я хотел бы назвать UDF, как показано ниже, и вернуть несколько (названных) столбцов.

SELECT get_data(columnname) FROM table; 

У меня возникли проблемы с поиском документации это делается, но слышал, что это возможно при использовании Generic UDF. Кто-нибудь знает, что нужно вернуть из метода оценки() для этого?

+0

Как это отличается от 'выберите ColumnName из таблицы;'? – gobrewers14

ответ

3

Я просто использую GenericUDTF. После того как вы напишете udf extends GenericUDTF, ваш udtf должен реализовать два важных метода: инициализировать и оценить.

  • В инициализации вы можете проверить тип аргумента и установить тип возвращаемого объекта. Например, с ObjectInspectorFactory.getStandardStructObjectInspector вы указываете выходные столбцы с именем из аргумента structFieldNames и тип значения столбца из structFieldObjectInspectors). Размер выходных столбцов - это размер списка structFieldNames. Существует две системы типа: java и hadoop. ObjectInspector java является begein с javaXXObjectInspector, иначе он начинается с writeableXXObjectInspector.
  • В процессе, он похож на общий udf. Кроме того, вы должны использовать ObjectInspector, который сохраняется из initialize(), чтобы преобразовать объект в конкретное значение, например String, Integer и т. Д. Функция переадресации для вывода строки. В объекте row 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

Пожалуйста, добавьте некоторые пояснения к вашему коду. –

Смежные вопросы