2015-02-06 49 views
4

我有一個樣品蜂房表創建爲蜂巢查詢記錄一個特定uniontype

CREATE TABLE union_test(foo UNIONTYPE<int, double, array<string>, struct<a:int,b:string>>); 

的數據可作爲

SELECT foo FROM union_test; 

被視爲輸出是

{0:1} 
{1:2.0} 
{2:["three","four"]} 
{3:{"a":5,"b":"five"}} 
{2:["six","seven"]} 
{3:{"a":8,"b":"eight"}} 
{0:9} 
{1:10.0} 

第一字段(標籤)表示聯合的類型(0表示int,1表示double,2表示數組等)。

我的問題是,如果我發現只選擇那些聯合類型爲2(數組)的記錄,應該如何構造我的查詢?

回答

3

Hive從UnionType中讀取數據沒有功能。所以我寫了2個UDF。一個獲得聯盟標籤(你試圖做),第二個獲得聯盟的結構作爲例子。

get_union_tag()函數:

package HiveUDF; 
import org.apache.hadoop.hive.ql.exec.Description; 
import org.apache.hadoop.hive.ql.exec.UDFArgumentException; 
import org.apache.hadoop.hive.ql.exec.UDFArgumentLengthException; 
import org.apache.hadoop.hive.ql.exec.UDFArgumentTypeException; 
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.UnionObjectInspector; 
import org.apache.hadoop.hive.serde2.objectinspector.primitive.PrimitiveObjectInspectorFactory; 


@Description(name = "get_union_tag", value = "_FUNC_(unionObject)" 
    + " - Returns union object Tag", extended = "Example:\n" + " > SELECT _FUNC_(unionObject) FROM src LIMIT 1;\n one") 
public class GetUnionTag extends GenericUDF { 

// Global variables that inspect the input. 
// These are set up during the initialize() call, and are then used during the 
// calls to evaluate() 
private transient UnionObjectInspector uoi; 

@Override 
// This is what we do in the initialize() method: 
// Verify that the input is of the type expected 
// Set up the ObjectInspectors for the input in global variables 
// Return the ObjectInspector for the output 
public ObjectInspector initialize(ObjectInspector[] arguments) throws UDFArgumentException {   

    // Verify the input is of the required type. 
    // Set the global variables (the various ObjectInspectors) while we're doing this 

    // Exactly one input argument 
    if(arguments.length != 1){ 
     throw new UDFArgumentLengthException("_FUNC_(unionObject) accepts exactly one argument."); 
    } 
    // Is the input an array<> 
    if(arguments[0].getCategory() != ObjectInspector.Category.UNION){ 
     throw new UDFArgumentTypeException(0,"The single argument to AddExternalIdToPurchaseDetails should be " 
       + "Union<>" 
       + " but " + arguments[0].getTypeName() + " is found"); 

    } 

    // Store the ObjectInspectors for use later in the evaluate() method 
    uoi = ((UnionObjectInspector)arguments[0]); 

    // Set up the object inspector for the output, and return it 
    return PrimitiveObjectInspectorFactory.javaByteObjectInspector; 
} 

@Override 
public Object evaluate(DeferredObject[] arguments) throws HiveException { 

    byte tag = uoi.getTag(arguments[0].get()); 
    return tag; 
} 

@Override 
public String getDisplayString(String[] children) { 

    StringBuilder sb = new StringBuilder(); 
    sb.append("get_union_tag("); 
    for (int i = 0; i < children.length; i++) { 
     if (i > 0) { 
      sb.append(','); 
     } 
     sb.append(children[i]); 
    } 
    sb.append(')'); 
    return sb.toString(); 
} 

}

功能get_struct_from_union()UDF:

package HiveUDF; 

import org.apache.hadoop.hive.ql.exec.Description; 
import org.apache.hadoop.hive.ql.exec.UDFArgumentException; 
import org.apache.hadoop.hive.ql.exec.UDFArgumentLengthException; 
import org.apache.hadoop.hive.ql.exec.UDFArgumentTypeException; 
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.StructObjectInspector; 
import org.apache.hadoop.hive.serde2.objectinspector.UnionObjectInspector; 

@Description(name = "get_union_struct", value = "_FUNC_(unionObject)" 
    + " - Returns struct ", extended = "Example:\n" + " > _FUNC_(unionObject).value \n 90.0121") 
public class GetUnionStruct extends GenericUDF { 

// Global variables that inspect the input. 
// These are set up during the initialize() call, and are then used during the 
// calls to evaluate() 
// 
// ObjectInspector for the list (input array<>) 
// ObjectInspector for the struct<> 
// ObjectInspectors for the elements of the struct<>, target, quantity and price 
private UnionObjectInspector unionObjectInspector; 
private StructObjectInspector structObjectInspector; 

@Override 
// This is what we do in the initialize() method: 
// Verify that the input is of the type expected 
// Set up the ObjectInspectors for the input in global variables 
// Return the ObjectInspector for the output 
public ObjectInspector initialize(ObjectInspector[] arguments) throws UDFArgumentException {   

    // Verify the input is of the required type. 
    // Set the global variables (the various ObjectInspectors) while we're doing this 

    // Exactly one input argument 
    if(arguments.length != 1){ 
     throw new UDFArgumentLengthException("_FUNC_(unionObject) accepts exactly one argument."); 
    } 
    // Is the input an array<> 
    if(arguments[0].getCategory() != ObjectInspector.Category.UNION){ 
     throw new UDFArgumentTypeException(0,"The single argument to AddExternalIdToPurchaseDetails should be " 
       + "Union<Struct>" 
       + " but " + arguments[0].getTypeName() + " is found"); 

    }   

    // Set up the object inspector for the output, and return it 
    return structObjectInspector; 
} 

@Override 
public Object evaluate(DeferredObject[] arguments) throws HiveException { 

    return ((UnionObjectInspector) unionObjectInspector).getField(arguments[0].get()); 
} 

@Override 
public String getDisplayString(String[] children) { 

    StringBuilder sb = new StringBuilder(); 
    sb.append("get_union_vqtstruct("); 
    for (int i = 0; i < children.length; i++) { 
     if (i > 0) { 
      sb.append(','); 
     } 
     sb.append(children[i]); 
    } 
    sb.append(')'); 
    return sb.toString(); 
} 

}

使用這些UDF's編譯和創建JAR文件。比上傳到配置單元(在我的情況下HDInsight)。不僅僅是使用

add jar wasb:///hive/HiveGUDF.jar; 
CREATE TEMPORARY FUNCTION get_union_struct AS 'HiveUDF.GetUnionStruct'; 

SELECT get_union_tag(exposed) FROM test;