Hive 数组类型的求和值
Posted
技术标签:
【中文标题】Hive 数组类型的求和值【英文标题】:Summing values of Hive array types 【发布时间】:2012-09-05 01:07:58 【问题描述】:Hive 有一个非常棒的 Array 类型,它在理论上非常有用,但是在实践中,我发现关于如何使用它进行任何类型的操作的信息非常少。 我们将一系列数字存储在数组类型的列中,并且需要在查询中对它们求和,最好是从第 n 个元素到第 m 个元素。是否可以使用标准 HiveQL 或是否需要 UDF 或客户映射器/缩减器?
注意:我们在 EMR 环境中使用 Hive 0.8.1。
【问题讨论】:
【参考方案1】:为此,我会写一个简单的UDF
。您需要在构建路径中包含 hive-exec
。
例如Maven
:
<dependency>
<groupId>org.apache.hive</groupId>
<artifactId>hive-exec</artifactId>
<version>0.8.1</version>
</dependency>
一个简单的原始实现如下所示:
package com.myexample;
import java.util.ArrayList;
import java.util.List;
import org.apache.hadoop.hive.ql.exec.UDF;
import org.apache.hadoop.io.IntWritable;
public class SubArraySum extends UDF
public IntWritable evaluate(ArrayList<Integer> list,
IntWritable from, IntWritable to)
IntWritable result = new IntWritable(-1);
if (list == null || list.size() < 1)
return result;
int m = from.get();
int n = to.get();
//m: inclusive, n:exclusive
List<Integer> subList = list.subList(m, n);
int sum = 0;
for (Integer i : subList)
sum += i;
result.set(sum);
return result;
接下来,构建一个 jar 并将其加载到 Hive shell 中:
hive> add jar /home/user/jar/myjar.jar;
hive> create temporary function subarraysum as 'com.myexample.SubArraySum';
现在您可以使用它来计算您拥有的数组的总和。
例如:
假设您有一个输入文件,其中包含制表符分隔的列:
1 0,1,2,3,4
2 5,6,7,8,9
将其加载到 mytable 中:
hive> create external table mytable (
id int,
nums array<int>
)
ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t'
COLLECTION ITEMS TERMINATED BY ','
STORED AS TEXTFILE
LOCATION '/user/hadoopuser/hive/input';
然后执行一些查询:
hive> select * from mytable;
1 [0,1,2,3,4]
2 [5,6,7,8,9]
在 m,n 范围内求和,其中 m=1, n=3
hive> select subarraysum(nums, 1,3) from mytable;
3
13
或者
hive> select sum(subarraysum(nums, 1,3)) from mytable;
16
【讨论】:
【参考方案2】:上面的答案解释得很好。我发布了一个非常简单的 UDF 实现。
package com.ak.hive.udf.test;
import java.util.ArrayList;
import org.apache.hadoop.hive.ql.exec.UDF;
public final class ArraySumUDF extends UDF
public int evaluate(ArrayList<Integer>arrayOfIntegers,int startIndex,int endIndex)
// add code to handle all index problem
int sum=0;
int count=startIndex-1;
for(;count<endIndex;count++)
sum+=arrayOfIntegers.get(count);
return sum;
同时发布表创建和其他查询。
create table table1 (col1 int,col2 array<int>)ROW FORMAT DELIMITED FIELDS TERMINATED BY ',' COLLECTION ITEMS TERMINATED BY '~' STORED AS TEXTFILE;
load data local inpath '/home/ak/Desktop/hivedata' into table table1;
我的输入文件看起来像
1,3~5~8~5~7~9 2,93~5~8~5~7~29 3,3~95~8~5~27~9 4,3~5~58~15~7~9 5,3~25~8~55~7~49 6,3~25~8~15~7~19 7,3~55~78~5~7~9
我已经创建了我的 UDF 的 jar,我使用以下命令将 jar 添加到 hive
add jar file:///home/ak/Desktop/array.jar;
然后我创建如图所示的临时函数
create temporary function getSum as 'com.ak.hive.udf.test.ArraySumUDF';
执行如下示例查询,
select col1,getSum(col2,1,3) from table1;
这应该可以解决最基本的需求。如果这不是问题陈述,请回复,以便我再次为您提供帮助。
【讨论】:
以上是关于Hive 数组类型的求和值的主要内容,如果未能解决你的问题,请参考以下文章
delphi 如何对动态数组求和(INT型),求最大值和最小值