【问题标题】:How to return Struct from Hive UDF?如何从 Hive UDF 返回结构?
【发布时间】:2014-11-19 11:39:06
【问题描述】:

我无法找到有关如何使用 Hive UDF 返回结构的文档。

我的主要问题是:

在 Java 中我从哪些类型的对象开始?

如何转换它们以便它们在 Hive 中被解释为结构?

【问题讨论】:

    标签: java hadoop hive user-defined-functions


    【解决方案1】:

    在 HIVE 中有一个 SerDe(序列化器和反序列化器)的概念,可以与您正在播放的数据格式一起使用。它序列化对象(复杂),然后根据需要对其进行反序列化。 例如,如果您有一个 JSON 文件,其中包含对象和值,那么您需要一种将内容存储在 hive 中的方法。 为此,您将使用 JsonSerde,它实际上是一个 jar 文件,包含用 java 编写的解析器代码,用于处理 Json 数据。

    现在您有了一个 jar (SerDe),另一个要求是存储该数据的模式。 例如:对于 XML 文件,您需要 XSD, 类似地,对于 JSON,您可以定义对象、数组和结构关系。 您可以查看此链接: http://thornydev.blogspot.in/2013/07/querying-json-records-via-hive.html 如果这有助于并解决您的目的,请告诉我:)

    【讨论】:

      【解决方案2】:

      下面是此类 UDF 的一个非常简单的示例。 它接收一个 User-Agent 字符串,使用外部库对其进行解析并返回一个包含 4 个文本字段的结构:

      STRUCT

      您需要扩展 GenericUDF 类并覆盖两个最重要的方法:initializeevaluate

      initialize() 描述结构本身并定义内部的数据类型。

      evaluate() 用实际值填充结构。

      您不需要任何特殊的类来返回,Hive 中的 struct 只是 Java 中的一个对象数组。

      import java.util.ArrayList;
      import org.apache.hadoop.hive.ql.exec.UDFArgumentException;
      import org.apache.hadoop.hive.ql.metadata.HiveException;
      import org.apache.hadoop.hive.ql.udf.generic.GenericUDF;
      import org.apache.hadoop.hive.serde2.objectinspector.ObjectInspector;
      import org.apache.hadoop.hive.serde2.objectinspector.ObjectInspectorFactory;
      import org.apache.hadoop.hive.serde2.objectinspector.StructObjectInspector;
      import org.apache.hadoop.hive.serde2.objectinspector.primitive.PrimitiveObjectInspectorFactory;
      import org.apache.hadoop.io.Text;
      
      import eu.bitwalker.useragentutils.UserAgent;
      
      public class UAStructUDF extends GenericUDF {
      
          private Object[] result;
      
          @Override
          public String getDisplayString(String[] arg0) {
              return "My display string";
          }
      
          @Override
          public ObjectInspector initialize(ObjectInspector[] arg0) throws UDFArgumentException {
              // Define the field names for the struct<> and their types
              ArrayList<String> structFieldNames = new ArrayList<String>();
              ArrayList<ObjectInspector> structFieldObjectInspectors = new ArrayList<ObjectInspector>();
      
              // fill struct field names
              // type
              structFieldNames.add("type");
              structFieldObjectInspectors.add(PrimitiveObjectInspectorFactory.writableStringObjectInspector);
              //family
              structFieldNames.add("family");
              structFieldObjectInspectors.add(PrimitiveObjectInspectorFactory.writableStringObjectInspector);
              // OS name
              structFieldNames.add("os");
              structFieldObjectInspectors.add(PrimitiveObjectInspectorFactory.writableStringObjectInspector);
              // device
              structFieldNames.add("device");
              structFieldObjectInspectors.add(PrimitiveObjectInspectorFactory.writableStringObjectInspector);
      
              StructObjectInspector si = ObjectInspectorFactory.getStandardStructObjectInspector(structFieldNames,
                      structFieldObjectInspectors);
              return si;
          }
      
          @Override
          public Object evaluate(DeferredObject[] args) throws HiveException {
              if (args == null || args.length < 1) {
                  throw new HiveException("args is empty");
              }
              if (args[0].get() == null) {
                  throw new HiveException("args contains null instead of object");
              }
      
              Object argObj = args[0].get();
      
              // get argument
              String argument = null;     
              if (argObj instanceof Text){
                  argument = ((Text) argObj).toString();
              } else if (argObj instanceof String){
                  argument = (String) argObj;
              } else {
                  throw new HiveException("Argument is neither a Text nor String, it is a " + argObj.getClass().getCanonicalName());
              }
              // parse UA string and return struct, which is just an array of objects: Object[] 
              return parseUAString(argument);
          }
      
          private Object parseUAString(String argument) {
              result = new Object[4];
              UserAgent ua = new UserAgent(argument);
              result[0] = new Text(ua.getBrowser().getBrowserType().getName());
              result[1] = new Text(ua.getBrowser().getGroup().getName());
              result[2] = new Text(ua.getOperatingSystem().getName());
              result[3] = new Text(ua.getOperatingSystem().getDeviceType().getName());
              return result;
          }
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-02-15
        • 2020-03-03
        • 1970-01-01
        相关资源
        最近更新 更多