在做数据聚合整理的时候,存在需要将同一ID的多列,合并成一个json,通过collcet_Set手动拼接json,手动效率不高,而且内置的UDF有连接符,最后生成的json格式怎么调试都不对,本想自己写UDF生成json,google后找到存在的UDF函数,先做以下记录:
HiveUDF添加主要分成两种方式
1、重编译Hive源码添加:添加UDF可以在Hive源码中增加新的UDF类,然后在一个FunctionRegistry类中注册,重编译Hive然后使用。
2、通过命令行添加:独立开发UDF,将UDF打包成jar,通过Hive命令行添加到系统中(实际上是调用了FunctionRegistry中的方法),于是产生了第三发UDF项目,如[Brickhouse](https://github.com/klout/brickhouse)
添加又分为临时和永久,临时适合于测试,当会话结束,函数会消失,永久添加会稳定添加到Hivemetastore中,重启会话然存在。
1、结果表的表结构map结构
create table if not exists temp.dws_result_package_1d_full_daily(
user_id string,
package map<string, string>,
package_detail map<string, map<string, string>>
)partitioned by (dt string)
stored AS parquet tblproperties('parquet.compression'='SNAPPY');
;
2、合并和合并json函数(collect 和to_json)
--导入udf
ADD jar /opt/UDF/brickhouse-0.7.1-SNAPSHOT.jar;
--创建临时UDF包collect
CREATE
TEMPORARY FUNCTION collect AS 'brickhouse.udf.collect.CollectUDAF';
--创建临时UDF包to_json
CREATE
TEMPORARY FUNCTION to_json AS 'brickhouse.udf.json.ToJsonUDF';
1)to_json可以将to_json(collect_set(字段名1)),将单列字段名1生成JSON串,生成的结果不带KEY值,格式为[{“value1”,“value2”…}]
这里在解释下collect_set collect_list的区别,collect_set 去重,collect_list不去重
2)collect可以将多列字段名,通过json的key-value方式结合,并且可以通过嵌套sort_array进行排序,其中得通过内置named_struct的UDF,组合为KEY-VALUE的格式,
to_json(sort_array(collect_set(named_struct(“key1”,字段名1,“key2”,字段名2… ))))
最后生成的json串带排序,且为key-value的格式
1)json只有一个key-value
add jar hdfs:////user/hadoop/profile/brickhouse-0.6.0.jar;
#创建临时函数
CREATE TEMPORARY FUNCTION collect AS 'brickhouse.udf.collect.CollectUDAF';
#执行组装数据
select collect('BOSS_MONTH_1', str_to_map(concat('order_id:', '123456')))
from dwd_dim.dwd_dim_terminal_prod_1d_full_daily where dt=20200707 limit 1;
add jar hdfs:////user/hadoop/profile/brickhouse-0.6.0.jar;
#创建临时函数
CREATE TEMPORARY FUNCTION collect AS 'brickhouse.udf.collect.CollectUDAF';
#创建临时函数
CREATE TEMPORARY FUNCTION to_json AS 'brickhouse.udf.json.ToJsonUDF';
#执行数据组装
select
to_json(sort_array(collect_set(named_struct('BOSS_MONTH_1', str_to_map(concat('order_id:', '123456')),'PERIOD_1', str_to_map(concat('order_id:', '121212'))))))
from dwd_dim.dwd_dim_terminal_prod_1d_full_daily where dt=20200707 limit 1;
2、聚合和聚合去重函数(combine和combine_unique)
--导入JAR
ADD jar /opt/UDF/brickhouse-0.7.1-SNAPSHOT.jar;
--创建临时函数
CREATE TEMPORARY FUNCTION combine AS 'brickhouse.udf.collect.CombineUDF';
CREATE TEMPORARY FUNCTION combine_unique AS 'brickhouse.udf.collect.CombineUniqueUDAF';
--执行结果
select combine_unique(combine(array('a','b','c'), array('b','c','d'))) from reqtable;
OK
--执行结果
["d","b","c","a"]
1、map函数构建map类型数据
create table temp.test_map_1 as
select 1 as uid, map("key1", "value1","key2", "value2") as map1 union all
select 2 as uid, map("key3", "value3","key4", "value4") as map1;