我正在尝试使用com.ibm.spss.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>
下面是我的Hive表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
有人能帮我吗?
2条答案
按热度按时间jslywgbw1#
文档中有一些这样的例子。https://github.com/dvasilen/hive-xml-serde/wiki/xml-data-sources
使用
text()
或者@Elementname
为您提供单个(原语)值,并且您的表已声明为allSTRING
列,您可能需要复杂类型来保存多个值,即map、struct或array。你看到的行为与(5)有关。复杂类型)。
“通过添加名为
<string>
"在您的示例中,您看到的结果是@start属性的3个值连接在一起,然后用
<string>
标签:您的xpath正在使用
@Start
以及@End
,而不是/*
不过,我很惊讶它居然奏效了。我理解你想要的结果,但我不确定它是否真的符合数据建模的方式。我认为
<Item>
实际上是一行。项目具有<TimeStamp>
,和<Title>
它有一个@id属性,还有一个名为<AlsoSeen>
对于@end&@start可以有多个值。从xml到配置单元表的直接Map可能是这样一种复杂的数据类型:ARRAY<STRUCT<End: TIMESTAMP, Start: TIMESTAMP>>
,一个包含结束和开始时间戳的结构数组。不幸的是,您的数据不符合hive所期望的时间戳的字符串格式,因此您可以按照https://cwiki.apache.org/confluence/display/hive/languagemanual+types#languagemanualtypes-时间戳
因此,您将得到这个table create语句(我已经删除了原始create表中的item\u artist和item\u author,因为serdeproperty中的这些列没有匹配的xpath)
注意我用于alsoseen字段的xpath:
"/Item/AlsoSeen"
这是上面链接的文档中的数组和结构的模式。它会给你这样的结果
item\u alsoseen列包含以下内容:一个由结构[]组成的数组(),用逗号分隔,每个结构都有结束和开始。
在那里,您可以使用
LATERAL VIEW explode()
技术例如
注意,因为我创建了alsoseen作为struct的数组
explode()
函数将每个结构作为一行返回。LATERAL VIEW
然后有效地进行交叉连接,或者更好地称为CROSS APPLY
得到笛卡尔积。参考配置单元数据类型:https://cwiki.apache.org/confluence/display/hive/languagemanual+types
bvpmtnay2#
自定义自定义项有数组索引和数值范围,很容易解决这个问题。为了使用函数,列类型应该是数组。请参阅后 hive 分解/侧视图多个阵列