【问题标题】:Create multiple columns from single Hive UDF从单个 Hive UDF 创建多个列
【发布时间】:2014-11-16 21:30:39
【问题描述】:

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

例如,我想调用一个像下面这样的 UDF 并返回几个(命名的)列。

SELECT get_data(columnname) FROM table;

我无法找到有关此操作的文档,但听说使用通用 UDF 是可能的。有谁知道需要从 evaluate() 方法返回什么才能使其工作?

【问题讨论】:

  • 这与select columnname from table; 有何不同?

标签: java hadoop hive user-defined-functions


【解决方案1】:

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

  • 在初始化中,您可以检查参数类型并设置返回对象类型。 例如,使用 ObjectInspectorFactory.getStandardStructObjectInspector,您可以使用来自 structFieldNames 参数的名称和来自 structFieldObjectInspectors 的列值类型指定输出列。输出列大小是 structFieldNames 列表的大小。 有两种类型系统:java和hadoop。 java的ObjectInspector以javaXXObjectInspector开头,否则以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 {

    }
}

【讨论】:

    猜你喜欢
    • 2021-05-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-12-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-11-10
    相关资源
    最近更新 更多