Hiveには、理論的には非常に便利なこの非常に優れた配列型がありますが、実践に関しては、Hiveを使用してあらゆる種類の操作を行う方法に関する情報はほとんど見つかりませんでした。一連の数値を配列型の列に格納し、クエリでそれらを合計する必要があります。できればn番目からm番目の要素までです。標準のHiveQLで可能ですか、それともUDFまたはカスタマーマッパー/リデューサーが必要ですか?
注:EMR環境ではHive0.8.1を使用しています。
Hiveには、理論的には非常に便利なこの非常に優れた配列型がありますが、実践に関しては、Hiveを使用してあらゆる種類の操作を行う方法に関する情報はほとんど見つかりませんでした。一連の数値を配列型の列に格納し、クエリでそれらを合計する必要があります。できればn番目からm番目の要素までです。標準のHiveQLで可能ですか、それともUDFまたはカスタマーマッパー/リデューサーが必要ですか?
注:EMR環境ではHive0.8.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シェルにロードします。
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
上記の答えは非常によく説明されています。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ファイルをハイブに追加します。
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;
これにより、非常に基本的なニーズが解決されます。これが問題の説明と異なる場合は、もう一度サポートさせていただきますので、返信してください。