HIVE之Map数据类型应用

使用场景

场景一 (博主实际使用场景)

  • 因为公司近期涉及埋点数据的业务逻辑,对于扩展字进行补充因此采用map数据类型存储扩展字段.

场景二 (其他业务场景)

  • 场景2.1
    我的项目里,生成的一个中间表,为了优化性能,里面有一列最好是个数组,因为如果把数组打散,每行上存一个元素,会因为其他列的重复导致数据量爆炸。首先想从上游表中生成这个数组,搜索半天文档,发现唯一的方式是把源数据列先转STRING,再用wm_concat聚合,再用split函数打散成ARRAY ,这样原来类型信息丢了,不过STRING似乎也能用,好,继续。后面的运算有个地方需要取数组最后一个元素,试图用数组下标配合size函数,my_array[size(my_array)], 发现报告错误,下标必须是常量,可是我的数组不是定长的,看看有没有函数能反转数组呢?没有!最后不得不放弃使用数组。。。

  • 场景2.2
    我的任务是为每个广告生成一个曲线,代表随着广告商的出价由低到高,预计的impression, click次数的曲线。最自然的表达是有个数据结构,里面存着出价,impression次数,click次数。可是ODPS不支持这样的用法,只好encode成一个字符串,每次操作先编码,再解码。好麻烦,效率也很差,可是没有办法。。。

工具
  • 作者使用的阿里云maxcompute工具,数据源在ES 使用阿里云数据集成脚本方式实现数据同步.备注因为数据源是String类型,阿里云的同步工具不支持将string 转为 map 数据类型.因此在数据同步过程中也就是ods层采用String类型进行数据存储,后续处理采用map数据类型. 使用Sqoop同步数据的话采用的方式作者一致

  • 如果你采用dataX的支持在序列换过程中将String类型转化为Map数据类型

建议格式
  • 扩展字段必须用String 同步源数据格式为 (KaTeX parse error: Expected 'EOF', got '#' at position 7: aaa:11#̲bbb:22#KaTeX parse error: Expected 'EOF', got '#' at position 13: key1:[{},{}]#̲key2:[{},{}])

    • 1.1 $的含义是用来区分扩展字段 (提高易读性)
    • 1.2 # 用来切分文本数据
    • 1.3 $key1":[{},{}] 这种复杂的数据格式 需要单独处理
    • 1.4 后续数据格式的处理使用map字段数据类型
样例场景
  • 建表语句
CREATE TABLE test_employee ( bar MAP<STRING,STRING>);
  • 导入数据
数据一
insert into TABLE test_employee
select str_to_map('"$aaa":"11"#"$bbb":"22"#"$key1":[{"shopId":"9033871623535131526","vehicleNum":"1"},{"shopId":"9033871623535131526","vehicleNum":"1"}]#"$key2":[{"shopId":"9033871623535131526","vehicleNum":"2"},{"shopId":"9033871623535131526","vehicleNum":"2"}]',"#",":");

数据二
insert into TABLE test_employee
select str_to_map('$aaa:11#$bbb:22#$key1:[{"shopId":"9033871623535131526","vehicleNum":"1"},{"shopId":"9033871623535131526","vehicleNum":"1"}]',"#",":");

  • 执行SQL (想知道结果的输出一定要自己动手、做人不可以懒啊)
select aa.user_id,bb.col,rr.shopId,rr.vehicleNum
from 
(SELECT user_id
        --arg3
        ,split(regexp_replace(regexp_extract(
                           arg3,
                           '^\\[(.+)\\]$',1),
            '\\}\\,\\{', '}||{'),'\\|\\|'    -- odps 格式
     ) as arg3_str
    -- '\\}\\,\\{', '}||{')  第三方云格式
FROM    prod_es_user_behavior_data_integration
WHERE   dt = 20200412
and      arg3 is not null
and      user_id in ("677132")
) aa 
-- 原因 1
-- 对于 [{},{},{}] 这种格式是无法直接进行解析 需要进行单独处理
-- regexp_replace,regexp_extract 这两种函数的使用要清楚
-- 上面的匹配原则可以通用、注意odps 与 第三方云平台的区别。
-- 不建议采用自定义函数处理上述结果、原因就是效率低
lateral view explode(aa.arg3_str) bb  as col
-- 原因 2  实现行转列
-- 使用json_tuple 对key 进行解析
lateral view json_tuple(bb.col,'shopId','vehicleNum') rr as shopId,vehicleNum
;

  • size函数 用来查看key的个数,返回的是int类型
select size(bar)  from test_employee;
  • map_keys 函数 用来查看key 返回array类型
select map_keys(bar) from test_employee;

  • map_values 函数 用来查看值 返回array类型
select map_values(bar) from test_employee;

  • str__to_map(str_,Delimiter1,Delimiter2)
Delimiter1 切分文本(文本的含义代表字符串的值)
Delimiter2 切分KV 
样例1
select str_to_map('"aaa":"11"&"bbb":"22"', ':');
错误输出 {"11"&"bbb":NULL, "22":NULL, "aaa":NULL}

样例2
select str_to_map('"aaa":"11"&"bbb":"22"', '&',':');
正确输出 {"aaa":"11", "bbb":"22"}

样例3
select str_to_map('"aaa":"11","bbb":"22","key1":"[{},{},{}]"', ',',':'); -- {"aaa":"11", "bbb":"22", "key1":"[{}, {}:NULL, {}]":NULL}
错误输出: 复杂的数据格式无法输出
特殊场景用法
  • 注意事项 1

  • 注意事项 2

  • 注意事项 3

    • 采用 lateral view + json__tuple 对于key进行解析,备注json_object 与 json_tuple 的区别就是可以解析 可以解析多个字段还是解析一个字段。
    • explode (array) 输入是数组 输出是行 一行转多行

福利分享
  • 复杂的数据类型可以进行嵌套 (扩展部分可以滤过)

  • 低频函数

  • 3
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值