Загрузка файла XML в таблицы Hive - PullRequest
0 голосов
/ 09 ноября 2018

Мы работаем над загрузкой полуструктурированного файла XML в таблицах Hive. Это данные о розничных покупках.
Я приложил образец XML-файла, чтобы понять, как выглядят данные, а также определение таблицы Hive, которое я использую для чтения этого XML-файла.

В файле есть несколько разделов "Платеж" и "Сумма" в разделе "Тендер" для каждой корзины в XML. Например, клиент может заплатить наличными, EFTPOS, кредитной картой, картой лояльности или иногда использовать их комбинацию.

При чтении данных из прикрепленного XML результаты показывают, что столбец Payment объединен с записями в XML, а для 'Amt' - NULL.

Я понял, что таблица, которую я использую для чтения данных, НЕ на 100% правильна.
Пожалуйста, дайте мне знать, как я могу создать несколько записей для одинаковых имен элементов "Payment" и "Amt", используя функции xpath

Я попытался найти какую-то документацию в интернете для этого и не смог найти ничего похожего на мой сценарий.

Пример данных:

<Bskt>
  <TillNo>4</TillNo>
  <BsktNo>1747</BsktNo>
  <DateTime>2017-10-31T10:51:25.000+11:00</DateTime>
  <OpID>10115</OpID>
  <Tender>
    <PayType>CSH</PayType>
    <Amt>46.75</Amt>
  </Tender>
  <Tender>
    <PayType>ITMLOY</PayType>
    <Amt>0</Amt>
    <CardNo>2679911927</CardNo>
    <Program>SmartRewards</Program>
    <Earn>46.00</Earn>
    <Burn>0.00</Burn>
  </Tender>
</Bskt>
<Bskt>
  <TillNo>4</TillNo>
  <BsktNo>1748</BsktNo>
  <DateTime>2017-10-31T10:53:11.000+11:00</DateTime>
  <OpID>10115</OpID>
  <Tender>
    <PayType>CSH</PayType>
    <Amt>46.75</Amt>
  </Tender>
  <Tender>
    <PayType>ITMLOY</PayType>
    <Amt>0</Amt>
    <CardNo>2619183833</CardNo>
    <Program>SmartRewards</Program>
    <Earn>46.00</Earn>
    <Burn>0.00</Burn>
  </Tender>
</Bskt>
<Bskt>
  <TillNo>4</TillNo>
  <BsktNo>1753</BsktNo>
  <DateTime>2017-10-31T11:19:34.000+11:00</DateTime>
  <OpID>50056</OpID>
  <Tender>
    <PayType>CSH</PayType>
    <Amt>28.10</Amt>
  </Tender>
  <Tender>
    <PayType>ITMLOY</PayType>
    <Amt>0</Amt>
    <CardNo>8263734549</CardNo>
    <Program>SmartRewards</Program>
    <Earn>28.00</Earn>
    <Burn>0.00</Burn>
  </Tender>
</Bskt>

Таблица улья:

CREATE EXTERNAL TABLE BASKET_TENDER (
`DateTime` string,
`BsktNo` double,
`TillNo` int,
`PayType` string,
`Amt` float,
`CardNo` string,
`Program` string,
`Earn` float,
`Burn` float
)

ROW FORMAT SERDE 'com.ibm.spss.hive.serde2.xml.XmlSerDe'
WITH SERDEPROPERTIES (

"column.xpath.DateTime"="/Bskt/DateTime/text()",
"column.xpath.BsktNo"="/Bskt/BsktNo/text()",
"column.xpath.TillNo"="/Bskt/TillNo/text()",
"column.xpath.PayType"="/Bskt/Tender/Paytype/text()",
"column.xpath.CardNo"="/Bskt/Tender/CardNo/text()",
"column.xpath.Amt"="/Bskt/Tender/Amt/text()",
"column.xpath.Program"="/Bskt/Tender/Program/text()",
"column.xpath.Earn"="/Bskt/Tender/Earn/text()",
"column.xpath.Burn"="/Bskt/Tender/Burn/text()"
)

STORED AS INPUTFORMAT 'com.ibm.spss.hive.serde2.xml.XmlInputFormat'
    OUTPUTFORMAT 
'org.apache.hadoop.hive.ql.io.parquet.MapredParquetOutputFormat' 
    LOCATION '<hdfs file location>'
    TBLPROPERTIES (
    "xmlinput.start"="<Bskt","xmlinput.end"="</Bskt>"
);

Вывод запроса Hive:

select * from BASKET_TENDER

Query result

1 Ответ

0 голосов
/ 09 ноября 2018

ПОЛУЧИТЬ только одно поле

Вы можете использовать оператор индекса ([]) для разбора xml. Тем не менее, убедитесь, что индекс начинается с 1, а не с 0.

В вашем случае, я полагаю, вы хотите второй случай тендера. Тогда просто используйте следующий путь XML.

"column.xpath.PayType"="/Bskt/Tender[2]/PayType/text()",
"column.xpath.CardNo"="/Bskt/Tender[2]/CardNo/text()",
"column.xpath.Amt"="/Bskt/Tender[2]/Amt/text()",

Это даст вам следующие значения.

enter image description here

Получить оба поля

если вы хотите получить оба поля как часть массива, вам нужно определить эти поля как массив и не предоставлять никаких операторов нижнего индекса при выборе xpath, как указано ниже

drop table temp.BASKET_TENDER;
CREATE EXTERNAL TABLE temp.BASKET_TENDER (
`DateTime` string,
`BsktNo` double,
`TillNo` int,
`PayType`  array<String>,
`Amt` array<float>,
`CardNo` array<string>,
`Program` string,
`Earn` float,
`Burn` float
)

ROW FORMAT SERDE 'com.ibm.spss.hive.serde2.xml.XmlSerDe'
WITH SERDEPROPERTIES (

"column.xpath.DateTime"="/Bskt/DateTime/text()",
"column.xpath.BsktNo"="/Bskt/BsktNo/text()",
"column.xpath.TillNo"="/Bskt/TillNo/text()",
"column.xpath.PayType"="/Bskt/Tender/PayType/text()",
"column.xpath.CardNo"="/Bskt/Tender/CardNo/text()",
"column.xpath.Amt"="/Bskt/Tender/Amt/text()",
"column.xpath.Program"="/Bskt/Tender/Program/text()",
"column.xpath.Earn"="/Bskt/Tender/Earn/text()",
"column.xpath.Burn"="/Bskt/Tender/Burn/text()"
)

STORED AS INPUTFORMAT 'com.ibm.spss.hive.serde2.xml.XmlInputFormat'
    OUTPUTFORMAT 
'org.apache.hadoop.hive.ql.io.parquet.MapredParquetOutputFormat' 
    LOCATION '/tmp/BASKET_TENDER'
    TBLPROPERTIES (
    "xmlinput.start"="<Bskt","xmlinput.end"="</Bskt>"
);

select * from temp.BASKET_TENDER;

Выход будет, как упоминалось, удар

enter image description here

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...