使用自定义分隔符导入配置单元中的复杂数据结构

uhry853o  于 2021-06-02  发布在  Hadoop
关注(0)|答案(1)|浏览(352)

我有一个巨大的数据集,其结构如下
fielda、fieldb、fieldc;菲尔德|菲尔德,菲尔德夫;菲尔德|菲尔德,菲尔德。。。
哪里:
fielda、fieldb和fieldc是应导入到单独列中的字符串
菲尔德|菲尔德,菲尔德夫;fieldg | fieldh,fieldi是一个数组(元素以分号分隔)的Map(元素以|分隔)的数组(元素以逗号分隔,例如fielde,fieldf)
我的问题是,初始数组用分号与fielda、fieldb、fieldc分开。我的问题是如何在创建表时正确设置分隔符。
虽然我提供了一个分号作为字段分隔符,但这个不识别数组

CREATE TABLE string_array(
    first_part STRING # this would be to store fieldA,fieldB,fieldC
   ,second_part ARRAY<STRING> # this would be to store fieldD|fieldE,FieldF;fieldG|fieldH,FieldI and split it by semicolon
       )
ROW FORMAT DELIMITED
    FIELDS TERMINATED BY '\\u003b'
    COLLECTION ITEMS TERMINATED BY '\\u003b'
    MAP KEYS TERMINATED BY '|'
STORED AS TEXTFILE;

LOAD DATA LOCAL INPATH '...' INTO TABLE string_array;

有什么办法让它发挥作用,这样我就可以在它的基础上再接再厉了吗?提前多谢了!

pxiryf3j

pxiryf3j1#

好问题。
我认为我们可以将这个问题分成两部分:(1)配置单元表结构和(2)数据分隔符。
让我们从查看配置单元表结构开始。如果我正确理解了您的数据结构(如果我没有理解,请纠正我),那么最能描述您的数据的表结构可以表示为:

CREATE TABLE string_array
AS
SELECT 'fieldA,fieldB,fieldC' AS first_part, array(map('fieldD', array('fieldE', 'FieldF')), map('fieldG', array('fieldH','FieldI'))) AS second_part;

请注意,字段第二部分是一个Map数组,其中每个Map的键引用一个字符串数组。换句话说,字段第二部分由数组中的Map中的数组组成。
如果我使用上面的语句来创建一个表,那么我就可以将生成的表复制到本地文件系统,并查看hive如何为其分配默认分隔符。我知道你不想使用默认分隔符,但请在这里忍受我。结果表的序列化磁盘表示形式如下所示:

00000000  66 69 65 6c 64 41 2c 66  69 65 6c 64 42 2c 66 69  |fieldA,fieldB,fi|
00000010  65 6c 64 43 01 66 69 65  6c 64 44 04 66 69 65 6c  |eldC.fieldD.fiel|
00000020  64 45 05 46 69 65 6c 64  46 02 66 69 65 6c 64 47  |dE.FieldF.fieldG|
00000030  04 66 69 65 6c 64 48 05  46 69 65 6c 64 49 0a     |.fieldH.FieldI.|

如果我们看看hive是如何看到分隔符的,我们注意到hive实际上看到了五种类型或级别的分隔符:

delimiter 1 = x'01' (between fieldC & fieldD) -- between first_part and second_part
delimiter 2 = x'02' (between fieldF & fieldG) -- between the two maps in the array of maps
delimiter 3 = x'03' not used
delimiter 4 = x'04' (between fieldD & fieldE) -- between the key and the array of fields within the map
delimiter 5 = x'05' (between fieldE & fieldF) -- between the fields within the array within the map

这就是你的问题所在。当前版本的配置单元(从0.11.0开始)只允许覆盖三个级别的分隔符。但是由于数据中的嵌套级别,hive需要超过三个级别的分隔符。
我的建议是预处理数据以使用配置单元的默认分隔符。使用这种方法,您应该能够将数据加载到配置单元中并引用它。

相关问题