Hive数组类型的求和值

Ale*_* N. 6 arrays hadoop hive aggregate aggregation

Hive有这个相当不错的Array类型,在理论上非常有用,但是当涉及到实践时,我发现很少有关于如何用它做任何类型的操作的信息.我们在数组类型列中存储一系列数字,并且需要在查询中对它们进行求和,最好是从第n个元素到第m个元素.是否可以使用标准HiveQL或是否需要UDF或客户映射器/缩减器?

注意:我们在EMR环境中使用Hive 0.8.1.

Lor*_*dig 9

UDF为此写了一个简单的文章.您需要拥有hive-exec构建路径.
例如,如果Maven:

<dependency>
  <groupId>org.apache.hive</groupId>
  <artifactId>hive-exec</artifactId>
  <version>0.8.1</version>
</dependency>
Run Code Online (Sandbox Code Playgroud)

一个简单的原始实现看起来像这样:

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;
    }
}
Run Code Online (Sandbox Code Playgroud)

接下来,构建一个jar并将其加载到Hive shell中:

hive> add jar /home/user/jar/myjar.jar;
hive> create temporary function subarraysum as 'com.myexample.SubArraySum';
Run Code Online (Sandbox Code Playgroud)

现在您可以使用它来计算您拥有的数组的总和.

例如:

假设您有一个输入文件,其中包含以制表符分隔的列:

1   0,1,2,3,4
2   5,6,7,8,9
Run Code Online (Sandbox Code Playgroud)

将其加载到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';
Run Code Online (Sandbox Code Playgroud)

然后执行一些查询:

hive> select * from mytable;
1   [0,1,2,3,4]
2   [5,6,7,8,9]
Run Code Online (Sandbox Code Playgroud)

在m,n中求和,其中m = 1,n = 3

hive> select subarraysum(nums, 1,3) from mytable;
3
13
Run Code Online (Sandbox Code Playgroud)

要么

hive> select sum(subarraysum(nums, 1,3)) from mytable;
16
Run Code Online (Sandbox Code Playgroud)