配置单元查询特定联合类型的记录 [英] hive querying records for a specific 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:五}}
{2:[six,seven]}
{3:{a:8,b:eight}}
{0:9}
{1:10.0}
(标签)表示联合的类型(0代表int,1代表double,2代表数组)。
我的问题是如果我发现只选择那些记录我的查询应该如何构造?
Hive中没有函数可以读取来自UnionType的数据。所以我写了2个UDF。一个获得联盟标签(你试图做),第二个获得联盟的结构作为例子。
get_union_tag()函数:
package HiveUDF;
导入org.apache.hadoop.hive.ql.exec.Description;
import org.apache.hadoop.hive.ql.exec.UDFArgumentException;
导入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)
+ - 返回联合对象标记,extended =示例:\\\
+> SELECT _FUNC_(unionObject)FROM src LIMIT 1; \ n one)
public class GetUnionTag extends GenericUDF {
//检查输入的全局变量。
//这些是在initialize()调用期间设置的,然后在
//调用期间用于evaluate()
私有瞬态UnionObjectInspector uoi;
@Override
//这就是我们在initialize()方法中所做的事情:
//验证输入是期望的类型
// Set在全局变量中输入ObjectInspectors
//返回输出的ObjectInspector $ b $ public ObjectInspector initialize(ObjectInspector [] arguments)throws UDFArgumentException {
//验证输入是必需的类型。
//设置全局变量(各种ObjectInspectors),而我们这样做
//只有一个输入参数
if(arguments.length!= 1){
抛出新的UDFArgumentLengthException(_ FUNC_(unionObject)只接受一个参数。);
}
//输入是一个数组<>
if(arguments [0] .getCategory()!= ObjectInspector.Category.UNION){
throw new UDFArgumentTypeException(0,AddExternalIdToPurchaseDetails的单个参数应该是
+Union< >
+但找到+ arguments [0] .getTypeName()+);
$ b //存储ObjectInspectors以便稍后在evaluate()方法中使用
uoi =((UnionObjectInspector)arguments [0]);
//为输出设置对象检查器,并返回它
return PrimitiveObjectInspectorFactory.javaByteObjectInspector;
$ b @Override
public Object evaluate(DeferredObject [] arguments)throws HiveException {
byte tag = uoi.getTag(arguments [0] 。得到());
返回标签;
$ b @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;
导入org.apache.hadoop.hive.ql.exec.Description;
import org.apache.hadoop.hive.ql.exec.UDFArgumentException;
导入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)
+ - 返回struct,extended =示例:\\\
+> _FUNC_ (unionObject).value \\\
90.0121)
public class GetUnionStruct extends GenericUDF {
//检查输入的全局变量。
//这些是在initialize()调用期间设置的,然后在
//调用期间用于评估()
//
// ObjectInspector获取列表(输入数组<>)
// ObjectInspector for the struct<>
// ObjectInspectors用于struct<> ;,目标,数量和价格的元素
private UnionObjectInspector unionObjectInspector;
private StructObjectInspector structObjectInspector;
@Override
//这就是我们在initialize()方法中所做的事情:
//验证输入是期望的类型
// Set在全局变量中输入ObjectInspectors
//返回输出的ObjectInspector $ b $ public ObjectInspector initialize(ObjectInspector [] arguments)throws UDFArgumentException {
//验证输入是必需的类型。
//设置全局变量(各种ObjectInspectors),而我们这样做
//只有一个输入参数
if(arguments.length!= 1){
抛出新的UDFArgumentLengthException(_ FUNC_(unionObject)只接受一个参数。);
}
//输入是一个数组<>
if(arguments [0] .getCategory()!= ObjectInspector.Category.UNION){
throw new UDFArgumentTypeException(0,AddExternalIdToPurchaseDetails的单个参数应该是
+Union<结构>
+但找到+ arguments [0] .getTypeName()+);
}
//设置输出的对象检查器,并返回它
return structObjectInspector;
$ b @Override
public Object evaluate(DeferredObject [] arguments)throws HiveException {
return((UnionObjectInspector)unionObjectInspector).getField(arguments [0]获得());
$ b @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编译并创建jar文件。比上传到配置单元(在我的情况下HDInsight)。比只使用
添加jar wasb:///hive/HiveGUDF.jar;
CREATE TEMPORARY FUNCTION get_union_struct AS'HiveUDF.GetUnionStruct';
SELECT get_union_tag(exposed)FROM test;
I have a sample hive table created as
CREATE TABLE union_test(foo UNIONTYPE<int, double, array<string>, struct<a:int,b:string>>);
The data can be viewed as
SELECT foo FROM union_test;
The output is
{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}
the first field (tag) denotes the type of the union ( 0 for int, 1 for double, 2 for array etc).
My problem is if I found to select only those records where the union type is 2 (array), how should I frame my query?
There is no function in Hive to read data from UnionType. So i wrote 2 UDF´s. One to get Union tag (that you trying to do) and second to get struct from union as an example.
get_union_tag() function:
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();
}
}
function 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();
}
}
to use these UDF´s compile and create jar file. Than upload into hive (in my case HDInsight). Than just use
add jar wasb:///hive/HiveGUDF.jar;
CREATE TEMPORARY FUNCTION get_union_struct AS 'HiveUDF.GetUnionStruct';
before u run e.g.
SELECT get_union_tag(exposed) FROM test;
这篇关于配置单元查询特定联合类型的记录的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!