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

Hive: create table statement where column formatted [k1:v1,k2:v2] is a map

我有来自 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 table:

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,因为用 [= 创建 table 似乎是错误的15=] 数据类型,但实际上是 map.

这是possible/practical吗?如果是,怎么做?

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

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

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

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