我有一张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的 CollectUDAF()
但这似乎不会将值附加到数组中,它只会更新它们。有什么想法吗?
编辑:这里有一个更详细的描述,这样我可以避免引用我在配置单元文档中尝试的函数。假设我有一张table
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()
,即使在传递两个参数并创建Map的示例中也是如此。它的输出是(如果在我的第一次编辑中应用到数据集)
1 {A:2, B:3}
2 {A:4, B:6}
正如我在最初的问题中所说的,它不会将值收集到数组中,而只是收集最后一个值(或更新数组)。
5条答案
按热度按时间kmynzznz1#
您当前的查询在内部和外部查询中按num分组—您需要按num分组
id
在内部查询中完成您要做的事情。f4t66c6m2#
在brickhouse中使用collect自定义项(http://github.com/klout/brickhouse )
这正是你需要的。如果使用一个参数,brickhouse的collect返回一个列表,如果使用两个参数,则返回一个map。
snvhrwxg3#
砖房里的收藏品(http://github.com/klout/brickhouse )我会带你去的。
关于您的评论编辑#2:
首先,将值收集到列表中,然后将k、v对收集到Map中:
会回来的
5t7ly7z54#
https://github.com/klout/brickhouse/blob/master/src/main/java/brickhouse/udf/collect/collectudaf.java#l55
请参阅brickhouse udaf,当args num大于1时,将使用mapcollectudafecaluator。
dw1jzc5e5#
如果不关心值的显示顺序,可以使用hive附带的collect\u set()udaf。
这应该能解决你的问题。