背景
在做**订单表的时候,发现订单产品部分的人群属性是在最内层的json中,但是人群的标识是不固定的值,也就是说json里面的key是不固定的,并且每个里面可能有多个key。get_json_object不能处理这种case。
{"1":{"Price":{"name":"CNY","amount":169.0},"settlePrice":{"name":"CNY","amount":147.0}},"2":{"Price":{"name":"CNY","amount":92.6},"settlePrice":{"name":"CNY","amount":80.0}}}
例如上述的json,处理完毕以后希望得到的结果是
1 Price 169 settlePrice 147
2 Price 92.6 settlePrice 80
调研
从网上搜类似的问题,得到的答案大搜是用java去写一个udf方法,先获取json的key然后根据具体的key去json中取对应的值。理论上这个办法是可行的,因为部门的udf工程权限和发布流程都很长,所以一个udf方法从开发到上线可能半天就过去了,开发效率得不到保证。如果能写脚本话的udf方法就会快很多。
hive UDF 方法
假设当前我们已经解析出了,json,order\_id,sku\_id,from\_date,to\_date 等几个字段在上级表中,接下来需要解析将json中的信息解析出来,python的uft如下:
# coding=utf-8
# __author__ = 'xiaoming'
import sys
reload(sys)
sys.setdefaultencoding('utf8')
import json
import os
AR_PRICE = 'ARPrice'
SETTLE_PRICE = 'settlePrice'
AMOUNT = 'amount'
for line in sys.stdin:
line,order_id,sku_id,from_date,to_date = line.strip('\n').split('\t')
band_prices = json.loads(line)
result = []
for key in band_prices.keys():
unit = band_prices[key]
ar_price = unit[AR_PRICE][AMOUNT]
settle_price = unit[SETTLE_PRICE][AMOUNT]
result.append(order_id+'\t'+key+'\t'+str(ar_price)+'\t'+str(settle_price)+'\t'+sku_id+'\t'+from_date+'\t'+to_date)
print '\n'.join(result)
在hive中加载上述文件:
add file ./test.py;
在hive sql中使用:
select
transform(band_prices,order_id,sku_id,from_date,to_date) USING 'python test.py' AS (order_id,people,AR_price,settle_price,sku_id,from_date,to_date)
from new_ploy_unit;
1.在hive中如果使用python的udf方法,必须将接下来都需要的字段全部放到udf中,不允许udf和单独的字段混合查询,下面的查询是不允许的
select
field1,
transform(field2) using 'python test.py' as (field3,field4)
from table
2. hive查询的结果字段默认是按照\t分割的,所以在python处理的时候要按照\t去切割。
3. 如果对于一行数据需要转成多行,在python的输出中用\n分割即可。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。