2012-09-12 50 views
6

Hive có kiểu mảng khá đẹp, rất hữu ích về mặt lý thuyết nhưng khi nói đến thực tế, tôi tìm thấy rất ít thông tin về cách làm bất kỳ loại opeartions nào với nó. Chúng tôi lưu trữ một số serie của các cột trong một cột kiểu mảng và cần SUM chúng trong một truy vấn, tốt hơn là từ phần tử n đến thứ m. Là nó có thể với HiveQL tiêu chuẩn hoặc hiện nó đòi hỏi một UDF hoặc khách hàng mapper/reducer?Giá trị tổng hợp của các loại mảng Hive

Lưu ý: chúng tôi đang sử dụng Hive 0.8.1 trong môi trường EMR.

Trả lời

9

Tôi muốn viết đơn giản UDF cho mục đích này. Bạn cần có hive-exec trong đường dẫn xây dựng của mình.
Ví dụ: Trong trường hợp Maven:

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

Một thực hiện liệu đơn giản sẽ trông như thế này:

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

Tiếp theo, xây dựng một jar và tải nó trong Hive shell:

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

Bây giờ bạn có thể sử dụng nó để tính tổng của mảng bạn có.

Ví dụ:

Giả sử rằng bạn có một tập tin đầu vào có cột tách biệt bởi tab trong đó:

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

tải nó vào 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'; 

Execute một số thắc mắc sau đó:

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

Sum nó trong phạm vi m, n nơi m = 1, n = 3

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

Hoặc

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

Câu trả lời ở trên được giải thích khá tốt. Tôi đăng một bản thực hiện rất đơn giản của 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; 
     } 
    } 

Cũng đăng bảng tạo và các truy vấn khác.

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; 

tập tin đầu vào của tôi sẽ như thế nào

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

Tôi đã tạo một chai UDF, tôi thêm thứ e jar để hive bằng cách sử dụng lệnh sau

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

Sau đó, tôi tạo ra chức năng tạm thời như

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

Thực hiện một truy vấn mẫu như dưới đây,

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

này nên giải quyết nhu cầu rất cơ bản . Trong trường hợp nếu đây không phải là tuyên bố vấn đề, vui lòng trả lời lại để tôi có thể giúp bạn lại.

Các vấn đề liên quan