我有一个Hive表,例如
id | value
-------------
A 1
A 2
B 3
A 4
B 5
基本上,我想模仿Python的defaultdict(list)
,并创建一个以id
为键,value
为值的地图。
查询:
select COLLECT_TO_A_MAP(id, value)
from table
输出:
{A:[1,2,4], B:[3,5]}
我尝试使用klout's 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}
正如我在原始问题中所述,它不会将值收集到它只收集最后一个数组的数组中(或更新数组)。
答案 0 :(得分:2)
在Brickhouse中使用collect UDF(http://github.com/klout/brickhouse)
这正是您所需要的。 Brickhouse'收集'如果使用了一个参数,则返回一个列表;如果使用两个参数,则返回一个映射。
答案 1 :(得分:1)
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]}
答案 2 :(得分:-1)
如果您不关心值的显示顺序,可以使用Hive附带的collect_set()UDAF。
SELECT id, collect_set(value) FROM table GROUP BY id;
这可以解决您的问题。
答案 3 :(得分:-1)
您的当前查询按内部和外部查询中的num分组 - 您需要在内部查询中按id
分组才能完成您尝试执行的操作。
答案 4 :(得分:-1)
请参见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}