【问题标题】:Hive: create table statement where column formatted [k1:v1,k2:v2] is a mapHive:创建表语句,其中格式化为 [k1:v1,k2:v2] 的列是映射
【发布时间】:2015-10-31 11:51:50
【问题描述】:

我想在 Hive 中查询来自 Mahout 推荐器的制表符分隔输出。建议如下所示:

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,因为当它实际上是 map 时,使用 string 数据类型创建表似乎是错误的。

这可能/实用吗?如果有,怎么做?

【问题讨论】:

    标签: hive hiveql


    【解决方案1】:

    看起来本质上,您正在对由非 Hive 程序(在本例中为 Mahout)生成的 TEXT 数据文件使用 EXTERNAL TABLE。

    如果文件格式与 Hive 在 TEXT 中序列化其 MAP 数据类型的方式兼容(由于包含括号,情况并非如此),我想你可以只“映射”一个 MAP key:value 列表中的列(请原谅双关语)。 例如,Google 将我指向 that post

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

    底线:如果您的目标只是扩展列表并提供具有“规范化”结构的另一个表,如您的示例代码所示,那么您使用 str_to_map() 的解决方案会更好,因为它更通用(可以管理括号...!)

    【讨论】:

      猜你喜欢
      • 2012-02-03
      • 2018-10-15
      • 2010-12-11
      • 1970-01-01
      • 1970-01-01
      • 2015-05-16
      • 1970-01-01
      • 1970-01-01
      • 2017-08-08
      相关资源
      最近更新 更多