在配置单元中使用横向视图时出现异常

o2rvlv0m  于 2021-05-29  发布在  Hadoop
关注(0)|答案(1)|浏览(405)

我使用下面的代码来解析hive中的xml数据。在我的xml数据中,有几个标记是重复的,所以我使用brickhouse jar和横向视图来解析标记并将其放置在配置单元表中。但是当我执行代码时,我得到了一个错误。请帮助我,因为我不能理解我做错了什么。
代码:

add jar /home/cloudera/brickhouse-0.5.5.jar;
CREATE TEMPORARY FUNCTION numeric_range AS 'brickhouse.udf.collect.NumericRange';
CREATE TEMPORARY FUNCTION array_index AS 'brickhouse.udf.collect.ArrayIndexUDF';
add jar /home/cloudera/hivexmlserde-1.0.5.3.jar;
set hive.exec.mode.local.auto=false;
DROP TABLE IF EXISTS medinfo2;
create table medinfo2 as
select array_index(statusCode,n) AS statusCode,
    array_index(startTime,n) AS startTime,
    array_index(endTime,n) AS endTime,
    array_index(strengthValue,n) AS strengthValue,
    array_index(strengthUnits,n) AS strengthUnits
from medications_info7 lateral view numeric_range(size( statusCode )) n1 as n;

错误:
引发原因:java.lang.indexoutofboundsexception:索引:7,大小:7 at java.util.arraylist.rangecheck(arraylist。java:635)在java.util.arraylist.get(arraylist。java:411)在com.ibm.spss.hive.serde2.xml.objectinspector.xmllistobjectinspector.getlistelement(xmllistobjectinspector。java:79)在brickhouse.udf.collect.arrayindexudf.evaluate(arrayindexudf。java:59)在org.apache.hadoop.hive.ql.exec.exprnodegenericfuncealuator.\u evaluate(exprnodegenericfuncealuator。java:186)位于org.apache.hadoop.hive.ql.exec.exprnodeevaluator.evaluate(exprnodeevaluator。java:77)在org.apache.hadoop.hive.ql.exec.exprnodeevaluatorhead.\u evaluate(exprnodeevaluatorhead。java:44)在org.apache.hadoop.hive.ql.exec.exprnodeevaluator.evaluate(exprnodeevaluator)。java:77)位于org.apache.hadoop.hive.ql.exec.exprnodeevaluator.evaluate(exprnodeevaluator。java:65)在org.apache.hadoop.hive.ql.exec.selectoperator.processop(selectoperator。java:77) ... 25个以上
失败:执行错误,返回代码2 from org.apache.hadoop.hive.ql.exec.mr.mapredtask mapreduce作业已启动:stage-stage-1:map:1 hdfs read:0 hdfs write:0 fail花费的mapreduce cpu总时间:0毫秒
样品:

<document>
 <code>10160-0</code>
 <entryInfo> 
    <statusCode>completed</statusCode>
    <startTime>20110729</startTime>
    <endTime>20110822</endTime>
    <strengthValue>24</strengthValue>
    <strengthUnits>h</strengthUnits>
 </entryInfo> 
 <entryInfo>
    <statusCode>completed</statusCode>
    <startTime>20120130</startTime>
    <endTime>20120326</endTime>
    <strengthValue>12</strengthValue>
    <strengthUnits>h</strengthUnits>
 </entryInfo>
 <entryInfo>
    <statusCode>completed</statusCode>
    <startTime>20100412</startTime>
    <endTime>20110822</endTime>
    <strengthValue>8</strengthValue>
    <strengthUnits>d</strengthUnits>
 </entryInfo>  
</document>

我的实际样品是巨大的大小,并包含了这些重复标签很多。

xmd2e60i

xmd2e60i1#

我不知道您的数据在hive中是什么样子的,因为您没有提供这些信息,所以下面是我如何将xml加载到hive中的。
装载机:

ADD JAR /path/to/jar/hivexmlserde-1.0.5.3.jar;

DROP TABLE IF EXISTS db.tbl;
CREATE TABLE IF NOT EXISTS db.tbl (
  code STRING,
  entryInfo ARRAY<MAP<STRING,STRING>>
)
ROW FORMAT SERDE 'com.ibm.spss.hive.serde2.xml.XmlSerde'
WITH SERDEPROPERTIES (
  "column.xpath.code"="/document/code/text()",
  "column.xpath.entryInfo"="/document/entryInfo/*"
)
STORED AS
INPUTFORMAT 'com.ibm.spss.hive.serde2.xml.XmlInputFormat'
OUTPUTFORMAT 'org.apache.hadoop.hive.ql.io.IgnoreKeyTextOutputFormat'
TBLPROPERTIES (
  "xmlinput.start"="<document>",
  "xmlinput.end"="</document>"
);

LOAD DATA LOCAL INPATH 'someFile.xml' INTO TABLE db.tbl;

在第3节“数组”下的HiveXMLSerde文档中,您可以看到它们使用数组结构来处理重复的标记,而在第4节“Map”中,您可以看到它们使用Map来处理子标记下的条目。所以, entryInfo 将是类型 ARRAY<MAP<STRING,STRING>> .
然后可以分解这个数组,像key/vals一样收集,然后重新组合。
查询:

ADD JAR /path/to/jar/hivexmlserde-1.0.5.3.jar;
ADD JAR /path/to/jars/brickhouse-0.7.1.jars;

CREATE TEMPORARY FUNCTION COLLECT AS 'brickhouse.udf.collect.CollectUDAF';

SELECT code
  , m_map['statusCode']    AS status_code
  , m_map['startTime']     AS start_time
  , m_map['endTime']       AS end_time
  , m_map['strengthValue'] AS strength_value
  , m_map['strengthUnits'] AS strength_units
FROM (
  SELECT code
    , COLLECT(m_keys, m_vals) AS m_map
  FROM (
    SELECT code
      , idx
      , MAP_KEYS(entry_info_map)[0]   AS m_keys
      , MAP_VALUES(entry_info_map)[0] AS m_vals
    FROM (
      SELECT code
        , entry_info_map
        , CASE
           WHEN FLOOR(tmp / 5) = 0 THEN 0
           WHEN FLOOR(tmp / 5) = 1 THEN 1
           WHEN FLOOR(tmp / 5) = 2 THEN 2
           ELSE -1
         END AS idx
      FROM db.tbl
      LATERAL VIEW POSEXPLODE(entryInfo) exptbl AS tmp, entry_info_map ) x ) y
  GROUP BY code, idx ) z

输出:

code    status_code     start_time      end_time    strength_value  strength_units
10160-0 completed       20110729        20110822    24              h
10160-0 completed       20120130        20120326    12              h
10160-0 completed       20100412        20110822    8               d

另外,这个问题你已经问了4次了(一,二,三,四)。这不是个好主意。只需询问一次,编辑以添加更多信息,并保持耐心。

相关问题