使用配置单元进行XML分析时出现多次问题



我正试图使用com.ibm.sps.Hive.serde2.XML.XmlSerDe从XML文件创建一个配置单元表。这对单次出现的标记非常有效。但我有一个多次发生的问题。

下面是我的源XML。

<Item>
<TimeStamp>2016-02-19T12:27:06.387Z</TimeStamp>
<AlsoSeen End="2014-08-21T13:44:32.557Z" Start="2014-08-21T13:44:04.637Z" />
<AlsoSeen End="2014-08-21T13:44:33.557Z" Start="2014-08-21T13:45:04.637Z" />
<AlsoSeen End="2014-08-21T13:44:34.557Z" Start="2014-08-21T13:46:04.637Z" />
<Title ID="112031424">FAULT IN OUR STARS, THE</Title>
<FileName>The Fault in Our Stars (2014) EXTENDED HDRip x264 AAC-CPG</FileName>
</Item>

下面是我的配置单元表DDL

add jar hivexmlserde-1.0.5.3.jar;
CREATE EXTERNAL TABLE xml_test
(
Item_TimeStamp String
,Item_AS_Start  String
,Item_AS_End    String
,Item_Title     String
,Item_ID        String
,Item_Artist    String
,Item_Author    String
,Item_FileName  String
)
ROW FORMAT SERDE 'com.ibm.spss.hive.serde2.xml.XmlSerDe'
WITH SERDEPROPERTIES (
"column.xpath.Item_TimeStamp"="/Item/TimeStamp/text()",
"column.xpath.Item_AS_Start"="/Item/AlsoSeen/@Start",
"column.xpath.Item_AS_End"="/Item/AlsoSeen/@End",  
"column.xpath.Item_Title"="/Item/Title/text()",   
"column.xpath.Item_ID"="/Item/Title/@ID",      
"column.xpath.Item_FileName"="/Item/FileName/text()"
)
STORED AS
INPUTFORMAT 'com.ibm.spss.hive.serde2.xml.XmlInputFormat'
OUTPUTFORMAT 'org.apache.hadoop.hive.ql.io.IgnoreKeyTextOutputFormat'
LOCATION '/user/xxxxxx/XML_text'
TBLPROPERTIES (
"xmlinput.start"="<Item>",
"xmlinput.end"="</Item>"
);

当我查询该表时,我得到以下值

2016-02-19T12:27:06.387Z <string>2014-08-21T13:44:04.637Z2014-08-21T13:45:04.637Z2014-08-21T13:46:04.637Z</string> <string>2014-08-21T13:44:32.557Z2014-08-21T13:44:33.557Z2014-08-21T13:44:34.557Z</string> FAULT IN OUR STARS, THE 112031424 The Fault in Our Stars (2014) EXTENDED HDRip x264 AAC-CPG 

但我预计输出应该是3条不同的线,AlsoSeen标签的3次不同出现如下

2016-02-19T12:27:06.387Z  2014-08-21T13:44:04.637Z 2014-08-21T13:44:32.557Z FAULT IN OUR STARS, THE 112031424 The Fault in Our Stars (2014) EXTENDED HDRip x264 AAC-CPG
2016-02-19T12:27:06.387Z  2014-08-21T13:45:04.637Z 2014-08-21T13:44:33.557Z FAULT IN OUR STARS, THE 112031424 The Fault in Our Stars (2014) EXTENDED HDRip x264 AAC-CPG  
2016-02-19T12:27:06.387Z  2014-08-21T13:46:04.637Z 2014-08-21T13:44:34.557Z FAULT IN OUR STARS, THE 112031424 The Fault in Our Stars (2014) EXTENDED HDRip x264 AAC-CPG

有人能帮我吗?

文档中有一些例子。https://github.com/dvasilen/Hive-XML-SerDe/wiki/XML-data-sources

使用text()@Elementname可以为您提供单个(基元)值,而且您的表已声明为所有STRING列,您可能需要复杂的类型来保存多个值,即Map、Struct或Array。

你所看到的行为与(5)有关。复杂类型)。

"用作基元类型的复杂内容将转换为通过添加名为<string>""的根元素来获得有效的XML字符串

在您的示例中,您看到的结果是@Start属性的3个值连接起来,然后用<string>标记包装:

<string>2014-08-21T13:44:04.637Z2014-08-21T13:45:04.637Z2014-08-21T13:46:04.637Z</string>

您的XPath使用的是@Start@End,而不是/*模式,所以我很惊讶它能起作用。

我理解你想要的结果,但我不确定它是否真的符合数据建模的方式。我认为<Item>实际上是一行。Item有一个<TimeStamp>和一个具有@ID属性的<Title>,它还有一个名为<AlsoSeen>的属性,该属性可以为@End&开始从XML到配置单元表的直接映射可能是以下复杂的数据类型:ARRAY<STRUCT<End: TIMESTAMP, Start: TIMESTAMP>>,一个包含结束和开始时间戳的结构数组。

不幸的是,您的数据不符合Hive所期望的时间戳的字符串格式,因此您可以根据https://cwiki.apache.org/confluence/display/Hive/LanguageManual+类型#语言手册类型时间戳

因此,您最终会得到这个表创建语句(我已经删除了原始创建表中的Item_Artist和Item_Author,因为SERDEPROPERTIES中的这些列没有匹配的xpath)

CREATE EXTERNAL TABLE xml_test
(
Item_TimeStamp String
,Item_AlsoSeen ARRAY<STRUCT<End: STRING, Start: STRING>>
,Item_Title     String
,Item_ID        String
,Item_FileName  String
)
ROW FORMAT SERDE 'com.ibm.spss.hive.serde2.xml.XmlSerDe'
WITH SERDEPROPERTIES (
"column.xpath.Item_TimeStamp"="/Item/TimeStamp/text()",
"column.xpath.Item_AlsoSeen"="/Item/AlsoSeen", 
"column.xpath.Item_Title"="/Item/Title/text()",   
"column.xpath.Item_ID"="/Item/Title/@ID",      
"column.xpath.Item_FileName"="/Item/FileName/text()"
)
STORED AS
INPUTFORMAT 'com.ibm.spss.hive.serde2.xml.XmlInputFormat'
OUTPUTFORMAT 'org.apache.hadoop.hive.ql.io.IgnoreKeyTextOutputFormat'
LOCATION '/user/xxxxxx/XML_text'
TBLPROPERTIES (
"xmlinput.start"="<Item>",
"xmlinput.end"="</Item>"
);

注意我用于AlsoSeen字段的xpath:"/Item/AlsoSeen"

这是上面链接的文档中数组和结构的模式。

它会给你像一样的结果

+--------------------+--------------------+--------------------+---------+--------------------+
|      Item_TimeStamp|       Item_AlsoSeen|          Item_Title|  Item_ID|       Item_FileName|
+--------------------+--------------------+--------------------+---------+--------------------+
|2016-02-19T12:27:...|[[2014-08-21T13:4...|FAULT IN OUR STAR...|112031424|The Fault in Our ...|
+--------------------+--------------------+--------------------+---------+--------------------+

Item_Alsosen列包含这一点,一个由逗号分隔的Structs[]组成的数组(),每个结构都有结束和开始。

WrappedArray([2014-08-21T13:44:32.557Z,2014-08-21T13:44:04.637Z], [2014-08-21T13:44:33.557Z,2014-08-21T13:45:04.637Z], [2014-08-21T13:44:34.557Z,2014-08-21T13:46:04.637Z])

从那里,您可以使用LATERAL VIEW explode()技术查询您想要的结果集

例如

SELECT
Item_TimeStamp,
--Item_AlsoSeen,
ias.End,
ias.Start,
Item_Title, 
Item_ID, 
Item_FileName
FROM xml_test
LATERAL VIEW explode(Item_AlsoSeen) ias as ias

注意,因为我将AlsoSeen创建为结构数组,所以explode()函数将每个结构作为一行返回。LATERAL VIEW然后有效地进行交叉连接,或者可能更好地称为CROSS APPLY,以获得笛卡尔乘积。

+--------------------+--------------------+--------------------+--------------------+---------+--------------------+
|      Item_TimeStamp|                 End|               Start|          Item_Title|  Item_ID|       Item_FileName|
+--------------------+--------------------+--------------------+--------------------+---------+--------------------+
|2016-02-19T12:27:...|2014-08-21T13:44:...|2014-08-21T13:44:...|FAULT IN OUR STAR...|112031424|The Fault in Our ...|
|2016-02-19T12:27:...|2014-08-21T13:44:...|2014-08-21T13:45:...|FAULT IN OUR STAR...|112031424|The Fault in Our ...|
|2016-02-19T12:27:...|2014-08-21T13:44:...|2014-08-21T13:46:...|FAULT IN OUR STAR...|112031424|The Fault in Our ...|
+--------------------+--------------------+--------------------+--------------------+---------+--------------------+

引用配置单元数据类型:https://cwiki.apache.org/confluence/display/Hive/LanguageManual+类型

有一些自定义编写的UDF,它们是array_index,numeric_range很容易解决问题。为了使用这些函数,列类型应该是数组。请参阅后Hive爆炸/横向视图多阵列

最新更新