收集到蜂巢中的地图

gob*_*s14 6 hadoop hive

我有一个Hive表,如

id  |  value
-------------
A      1
A      2
B      3
A      4
B      5
Run Code Online (Sandbox Code Playgroud)

从本质上讲,我想模仿Python defaultdict(list)并创建一个带有id键和value值的地图.

查询:

select COLLECT_TO_A_MAP(id, value)
from table
Run Code Online (Sandbox Code Playgroud)

输出:

{A:[1,2,4], B:[3,5]}
Run Code Online (Sandbox Code Playgroud)

我尝试使用klout, CollectUDAF()但似乎这不会将值附加到数组,它只会更新它们.有任何想法吗?

编辑: 这是一个更详细的描述,所以我可以避免引用我在Hive文档中尝试函数的答案.假设我有一张桌子

num    |id    |value
____________________
1       A      1
1       A      2
1       B      3
2       A      4
2       B      5
2       B      6
Run Code Online (Sandbox Code Playgroud)

我正在寻找的是提供此输出的UDAF

num     |new_map
________________________
1       {A:[1,2], B:[3]}
2       {A:[4], B:[5,6]}
Run Code Online (Sandbox Code Playgroud)

对此查询

select num
      ,COLLECT_TO_A_MAP(id, value) as new_map
from table
group by num
Run Code Online (Sandbox Code Playgroud)

有一种解决方法可以实现这一目标.可以通过在诸如的查询中使用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
Run Code Online (Sandbox Code Playgroud)

但是,我宁愿不写一个嵌套查询.

编辑#2

(正如我在原始问题中所提到的)我已经尝试过使用Klout CollectUDAF(),即使在你传递两个参数的实例中它也创建了一个地图.它的输出是(如果在我的第一次编辑中应用于数据集)

1    {A:2, B:3}
2    {A:4, B:6}
Run Code Online (Sandbox Code Playgroud)

正如我原来的问题所述,它不会将值收集到它只收集最后一个数组(或更新数组)的数组中.

Nis*_*kar -1

如果您不关心值出现的顺序,您可以使用 Hive 附带的collect_set() UDAF。

SELECT id, collect_set(value) FROM table GROUP BY id;
Run Code Online (Sandbox Code Playgroud)

这应该可以解决你的问题。