使用hive解析xml时的多次出现问题

gywdnpxw  于 2021-06-29  发布在  Hive
关注(0)|答案(2)|浏览(260)

我正在尝试使用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

有人能帮我吗?

jslywgbw

jslywgbw1#

文档中有一些这样的例子。https://github.com/dvasilen/hive-xml-serde/wiki/xml-data-sources
使用 text() 或者 @Elementname 为您提供单个(原语)值,并且您的表已声明为all STRING 列,您可能需要复杂类型来保存多个值,即map、struct或array。
你看到的行为与(5)有关。复杂类型)。
“通过添加名为 <string> "
在您的示例中,您看到的结果是@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> 实际上是一行。项目具有 <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)

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\u alsoseen列包含以下内容:一个由结构[]组成的数组(),用逗号分隔,每个结构都有结束和开始。

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作为struct的数组 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+types

bvpmtnay

bvpmtnay2#

自定义自定义项有数组索引和数值范围,很容易解决这个问题。为了使用函数,列类型应该是数组。请参阅后 hive 分解/侧视图多个阵列

相关问题