3

我正在使用 gzip 压缩的 JSON 编码文件在 Amazon 的 Elastic MapReduce 上创建 Hive 表。我正在使用这个 JSON SerDe:http ://code.google.com/p/hive-json-serde/

未编码的文件如下所示:

{"id":"101", "items":"A:231,234,119,12"}

{"id":"102", "items":"B:13,89,121"}

...

我想为具有表格生成功能的用户创建一个“项目”列的数组。我想要的数组是整数的“爆炸”CSV,忽略“:”和它之前的字母。我希望能够对项目整数(231,234 等)进行 GROUP BY 或将它们与其他表相结合。改变这个文件的格式会很困难,我所有的旧数据都以这种格式存储,所以我想在 Hive 中解决这个问题,而不改变如何存储我的数据。

我有办法做到这一点吗?

编辑:

谢谢@mark-grover,这行得通!

我做了这样的事情:

SELECT id, item FROM my_table LATERAL VIEW explode(split(substr(items, 3, length(items) - 2), ',')) t1 AS item

要得到:

101 231

101 234

101 119

101  12

102  13

102  89

102 121

在这样做的过程中,我发现我想做更多的事情。我还想选择每个项目在 CSV 中的位置。所以我希望输出看起来像:

101 231 0

101 234 1

101 119 2

101  12 3

102  13 1

102  89 2

102 121 3

这里有什么想法吗?

再次编辑:

我为我的后续问题提出了一些类似的问题:

SELECT id, item, find_in_set(item, substr(items, 3, length(items) - 2)) AS position
FROM my_table LATERAL VIEW explode(split(substr(items, 3, length(items) - 2), ',')) t1 AS item
4

1 回答 1

4

您可以使用Hive UDF来做到这一点。您可能希望使用拆分 UDF 以逗号拆分字符串以获取数组,然后使用横向视图和分解 UDTF来“分解”数组的内容。

回答你的第二个问题:这是我现在能想到的。可能有更好/更容易/更少hackier的方法来做到这一点。

创建一个 UDF,例如 split_extended,它将作为具有 2 个元素的结构返回,第一个是数组元素的实际内容,第二个是索引。当你分解这个时,分解列的类型将是一个结构。此结构的条目之一是数组中的实际元素,另一个是与该元素对应的索引。

如果您考虑一下,我们正在扩充拆分 UDF 以返回 2 条信息 - 元素和索引。这些是将此类信息作为单个对象返回的几种方法 - 结构是其中之一,数组是另一个(数组的第一个元素是数组中的实际元素,第二个元素是索引)。返回 2 条信息的另一种更巧妙的方法是将它们与您知道数据中不存在的东西(比如“:”)连接起来,这样您就可以让 UDF 返回“231:0”、“234:0” '、'119:2' 等,最后,您可以根据 ':' (使用拆分 UDF)将结果字符串拆分出来,而不是访问它们的成员,以获得所需的两部分。

要创建您自己的 UDF,您将能够利用此处提供的大部分(如果不是全部)拆分 UDF 代码。

于 2012-12-07T06:53:19.217 回答