2012-09-12 21 views
6

Hive型は非常に有益なArray型で、理論的には非常に便利ですが、練習する際には、どのようにopeartionsを実行するかに関する情報はほとんど見つかりませんでした。 配列型の列に数値のセリを格納し、それらを問​​合せ、好ましくはn番目からm番目の要素にSUMする必要があります。標準のHiveQLで可能か、それともUDFや顧客マッパー/レデューサーが必要ですか?Hive配列型の集計値

注:EMR環境でHive 0.8.1を使用しています。

答えて

9

私はこの目的のために単純な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> add jar /home/user/jar/myjar.jar; 
hive> create temporary function subarraysum as 'com.myexample.SubArraySum'; 

これで、配列の合計を計算することができます。

例:

のは、あなたがそれで、タブで区切られた列の入力ファイルを持っていると仮定しましょう:mytableはへ

1 0,1,2,3,4 
2 5,6,7,8,9 

ロード、それを:

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 
1

上記の答えは非常によく説明されます。私は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ファイルを作成しました。

create temporary function getSum as 'com.ak.hive.udf.test.ArraySumUDF'; 

は、以下のようにサンプルクエリを実行示すように、電子ジャーは、その後、私は一時的な関数を作成し、次のコマンド

add jar file:///home/ak/Desktop/array.jar; 

を使用してハイブに

select col1,getSum(col2,1,3) from table1; 

これは非常に基本的なニーズを解決する必要があります。場合は、これが問題の声明ではない場合は、私は再びあなたを助けることができるように返信してください。