2012-09-12 27 views
6

Hive, teoride çok yararlı olan oldukça hoş bir Array türüne sahiptir, ancak pratik olduğunda, onunla her türlü opeartyonun nasıl yapılacağına dair çok az bilgi buldum. Dizi dizisi sütununa bir sayı dizisi depolar ve bunları bir sorguda, tercihen n-th öğesinden öğeye SUMMALIDIR. Standart HiveQL ile mümkün mü veya bir UDF veya müşteri mapper/redüktör gerektiriyor mu?Hive dizisi türlerinin toplam değerleri

Not: EMR ortamında Hive 0.8.1 kullanıyoruz.

cevap

9

Bu amaçla basit bir UDF yazabilirim. Yapı yolunuzda hive-exec olması gerekir. Maven durumunda
Örn:

<dependency> 
    <groupId>org.apache.hive</groupId> 
    <artifactId>hive-exec</artifactId> 
    <version>0.8.1</version> 
</dependency> 

Basit ham uygulama aşağıdaki gibi görünecektir:

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; 
    } 
} 

Sonraki, bir kavanoz inşa etmek ve kovan kabuğunda yüklemek:

hive> add jar /home/user/jar/myjar.jar; 
hive> create temporary function subarraysum as 'com.myexample.SubArraySum'; 

Şimdi sahip olduğunuz dizinin toplamını hesaplamak için kullanabilirsiniz.

Örn: mytable içine

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

Yük it:

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'; 

sonra bazı sorguları yürütme

en Eğer içinde sekme ayrılmış sütunları olan bir giriş dosyası olduğunu varsayalım:

hive> select * from mytable; 
1 [0,1,2,3,4] 
2 [5,6,7,8,9] 

aralığı m toplamı o, n, burada m = 1, n = 3

hive> select subarraysum(nums, 1,3) from mytable; 
3 
13 

ya

hive> select sum(subarraysum(nums, 1,3)) from mytable; 
16 
1

yukarıda cevap oldukça iyi açıklanmıştır. UDF'nin çok basit bir uygulamasını yayınlıyorum. Ayrıca, tablo oluşturma ve diğer sorguları da yayınlayın.

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; 

Benim girdi dosyası gibi görünecektir

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'imden bir kavanoz oluşturdum.

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

aşağıda bir örnek sorgu gerçekleştirin gösterildiği gibi e kavanoz, Sonra geçici işlev oluşturmak aşağıdaki komutu

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

kullanarak kovanına

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

Bu çok temel ihtiyaç çözmek gerekir . Eğer sorun ifadesi bu değilse, lütfen tekrar cevap verebilmemiz için lütfen tekrar yanıt verin.