Hive:创建表语句,其中列格式为[k1:v1,k2:v2]是一个映射

时间:2015-08-07 23:02:25

标签: hive hiveql

我有一个Mahout推荐器的制表符分隔输出,我想在Hive中查询。建议如下:

54508 [19:4.9,22:3.5]
54584 [17:5.2]
54648 [13:6.1,3:5.9]
54692 [17:8.1]
55424 [1:3.8]
55448 [16:2.7,3:1.2]
55452 [17:6.8]
57084 [42:6.8,3:5.4]
57212 [17:3.5]

有两列:第一列包含用户ID,第二列包含推荐产品列表及其预期评级。

我创建了一个Hive表:

CREATE TABLE `recommendations_raw`(
  user int, 
  recommendations string)
ROW FORMAT DELIMITED 
  FIELDS TERMINATED BY '\t' 
STORED AS INPUTFORMAT 
  'org.apache.hadoop.mapred.TextInputFormat' 
OUTPUTFORMAT 
  'org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormat'
LOCATION
  '/etl/recommender/output';

我可以在Hive查询中将数据转换为长表格形式:

select
   user,
   product,
   rating
from recommendations_raw
lateral view explode(str_to_map(substr(recommendations, 2, length(recommendations) - 2), ",", ":")) product_rating as product, rating

user    product   rating
54508   19        4.9
54508   22        3.5
54584   17        5.2
[etc...]

但是,我宁愿在create table语句中创建映射,而不是在查询中使用str_to_map,因为当它真的是{{string数据类型时创建一个表似乎是错误的。 1}}。

这可行/实用吗?如果是这样,怎么样?

1 个答案:

答案 0 :(得分:1)

从本质上讲,您在非Hive程序(在本例中为Mahout)生成的TEXT数据文件上使用EXTERNAL TABLE。

如果文件格式与Hive在TEXT中序列化其MAP数据类型的方式兼容(由于括号括起而不是这种情况),我想你可能只是" map& #34; key:value列表中的MAP列(原谅双关语)。 谷歌向我指出that post为例。

但无论如何,TEXT是TEXT。 Hive必须在每次读取时反序列化映射,无论是隐式地(在MAP列定义的情况下)还是显式地(在STRING列加上用户定义的str_to_map()的情况下)。

底线:如果您的目标只是爆炸列表并使用"标准化"提供另一个表格。结构,如示例代码所示,那么使用str_to_map()的解决方案更好,因为它更通用(可以管理括号......!)