복붙노트

[HADOOP] 하이브의지도 수집

HADOOP

하이브의지도 수집

나는 다음과 같은 하이브 테이블을 가지고있다.

id  |  value
-------------
A      1
A      2
B      3
A      4
B      5

본질적으로, 나는 파이썬의 defaultdict (list)를 모방하고 키와 값으로 id를 값으로 가지는 맵을 생성하고 싶다.

질문:

select COLLECT_TO_A_MAP(id, value)
from table

산출:

{A:[1,2,4], B:[3,5]}

나는 klout의 CollectUDAF ()를 사용해 보았지만 배열에 값을 추가하지 않는 것으로 보입니다. 단지 값을 업데이트 할 것입니다. 어떤 아이디어?

편집하다: 다음은 더 자세한 설명이므로 Hive 설명서에서 기능을 시도하는 참조를 피할 수 있습니다. 내가 테이블을 가지고 있다고 가정 해보자.

num    |id    |value
____________________
1       A      1
1       A      2
1       B      3
2       A      4
2       B      5
2       B      6

내가 찾고있는 것은이 결과물을 제공하는 UDAF를위한 것이다.

num     |new_map
________________________
1       {A:[1,2], B:[3]}
2       {A:[4], B:[5,6]}

이 쿼리에

select num
      ,COLLECT_TO_A_MAP(id, value) as new_map
from table
group by num

이 문제를 해결할 수있는 해결 방법이 있습니다. 그것은 Klout (위에서 언급 한 UDAF 참조) CollectUDAF ()를 사용하여 다음과 같은 쿼리에서 모방 될 수 있습니다.

add jar '~/brickhouse/target/brickhouse-0.6.0.jar'
create temporary function collect as 'brickhouse.udf.collect.CollectUDAF';

select num
       ,collect(id_array, value_array) as new_map
from (
      select collect_list(id) as id_array
            ,collect_list(value) as value_array
            ,num
      from table
      group by num
     ) A
group by num

그러나 중첩 된 쿼리를 작성하지는 않습니다.

2 번 수정

(원래의 질문에서 언급했듯이) 저는 이미 Klout의 CollectUDAF ()를 사용해 보았습니다. 심지어 두 개의 매개 변수를 전달하고지도를 만드는 경우에도 마찬가지입니다. 그 결과는 (첫 번째 편집에서 데이터 세트에 적용된 경우)

1    {A:2, B:3}
2    {A:4, B:6}

원래 질문에서 언급했듯이 배열에 값을 수집하지 않고 마지막 값을 수집합니다 (또는 배열을 업데이트합니다).

해결법

  1. ==============================

    1.Brickhouse (http://github.com/klout/brickhouse)에서 수집 UDF를 사용하십시오.

    Brickhouse (http://github.com/klout/brickhouse)에서 수집 UDF를 사용하십시오.

    그것은 정확히 당신이 필요로하는 것입니다. Brickhouse의 'collect'는 한 매개 변수가 사용되면 목록을 반환하고 두 개의 매개 변수가 사용되는 경우지도를 반환합니다.

  2. ==============================

    2.Brickhouse에있는 CollectUDAF (http://github.com/klout/brickhouse)가 당신을 거기에 데려다 줄 것입니다.

    Brickhouse에있는 CollectUDAF (http://github.com/klout/brickhouse)가 당신을 거기에 데려다 줄 것입니다.

    귀하의 의견과 관련하여 편집 # 2 :

    먼저 목록에 값을 수집 한 다음 k, v 쌍을 맵에 수집하십시오.

    select
        num,
        collectUDAF(id, values) as new_map
    from
        (
        SELECT
            num,
            id,
            collect_set(value) as values
        FROM
            tbl
        GROUP BY
            num,
            id
        ) as sub
    GROUP BY
        num
    

    돌아올거야.

    num  | new_map
    ________________________
    1      {A:[1,2], B:[3]}
    2      {A:[4], B:[5,6]}
    
  3. ==============================

    3.값의 순서에 신경 쓰지 않는다면 Hive와 함께 제공되는 collect_set () UDAF를 사용할 수 있습니다.

    값의 순서에 신경 쓰지 않는다면 Hive와 함께 제공되는 collect_set () UDAF를 사용할 수 있습니다.

    SELECT id, collect_set(value) FROM table GROUP BY id;
    

    이렇게하면 문제가 해결됩니다.

  4. ==============================

    4.내부 쿼리와 외부 쿼리 모두에서 현재 쿼리 그룹을 숫자로 그룹화합니다. 수행하려는 작업을 수행하려면 내부 쿼리에서 ID별로 그룹화해야합니다.

    내부 쿼리와 외부 쿼리 모두에서 현재 쿼리 그룹을 숫자로 그룹화합니다. 수행하려는 작업을 수행하려면 내부 쿼리에서 ID별로 그룹화해야합니다.

  5. ==============================

    5.https://github.com/klout/brickhouse/blob/master/src/main/java/brickhouse/udf/collect/CollectUDAF.java#L55

    https://github.com/klout/brickhouse/blob/master/src/main/java/brickhouse/udf/collect/CollectUDAF.java#L55

    brickhouse udaf를 보면 args num이 1보다 크면 MapCollectUDAFEvaluator가 사용됩니다.

    add jar */brickhouse.jar ;
    create temporary function collect  as 'brickhouse.udf.collect.CollectUDAF';
    select 
    collect(a,b)
    from( select 1232123 a,21 b 
        union all select 123 a,23 b)a;
    
    
    result:{1232123:21,123:23}
    
  6. from https://stackoverflow.com/questions/24826530/collect-to-a-map-in-hive by cc-by-sa and MIT license