regex

gcuhipw9  于 2021-06-24  发布在  Hive
关注(0)|答案(2)|浏览(238)

所以,我一直在试着把CSV从s3桶装到雅典娜。但是,csv的设计方式如下所示

ns=2;s=A_EREG.A_EREG.A_PHASE_PRESSURE,102.19468,12/12/19 00:00:01.2144275 GMT
ns=2;s=A_EREG.A_EREG.A_PHASE_REF_SIGNAL_TO_VALVE,50.0,12/12/19 00:00:01.2144275 GMT
ns=2;s=A_EREG.A_EREG.A_PHASE_SEC_CURRENT,15.919731,12/12/19 00:00:01.2144275 GMT
ns=2;s=A_EREG.A_EREG.A_PHASE_SEC_VOLTAGE,0.22070877,12/12/19 00:00:01.2144275 GMT
ns=2;s=A_EREG.A_EREG.ACTIVE_PWR,0.0,12/12/19 00:00:01.2144275 GMT

csv只是一个记录。记录的每一列都有一个与之相关联的值,它位于时间戳和名称之间的两个逗号之间,我正试图捕获它。我试着用regex-serde解析它,得到了一个正则表达式:

((?<=\,).*?(?=\,))

演示我希望上面的输出是:

col_a       col_b    col_c      col_d          col_e 
102.19468   50.0     15.919731  0.22070877     0.0

我的ddl查询如下所示:

CREATE EXTERNAL TABLE IF NOT EXISTS
(...)
ROW FORMAT SERDE 'org.apache.hadoop.hive.serde2.RegexSerDe'
WITH SERDEPROPERTIES (
  'serialization.format' = '1',
  'input.regex' = "\(?<=\,).*?(?=\,)"
) LOCATION 's3://jackson-nifi-plc-data-1/2019-12-12/'
TBLPROPERTIES ('has_encrypted_data'='false');

上面的表创建查询工作成功,但当我尝试预览表时,出现以下错误:

HIVE_CURSOR_ERROR: Number of matching groups doesn't match the number of columns

我对Hive和正则表达式还比较陌生,所以我不知道发生了什么。有人能帮帮我吗?
谢谢你,比尔

mrfwxfqh

mrfwxfqh1#

配置单元表中的一列对应于正则表达式中的一个捕获组。如果要选择包含逗号之间的所有内容的单列,则可以这样做:

'.*,(.*),.*'
yquaqz18

yquaqz182#

雅典娜·塞德斯要求输入中的每条记录都是一行。不支持多行记录。
相反,您可以创建一个表,将数据中的每一行Map到表中的一行,并使用视图将属于同一行的行透视到一行中。
我假设 ns 行开头的字段是一个id,如果不是,我假设还有其他东西可以标识哪些行属于一起,您可以使用。
我用你的演示创建了一个正则表达式,它匹配每一行的所有字段,并产生了 ns=(\d);s=([^,]+),([^,]+),(.+) (见https://regex101.com/r/hnjnxk/5).

CREATE EXTERNAL TABLE my_data (
  ns string,
  s string,
  v double,
  dt string
)
ROW FORMAT SERDE 'org.apache.hadoop.hive.serde2.RegexSerDe'
WITH SERDEPROPERTIES (
  'serialization.format' = '1',
  'input.regex' = "ns=(\\d);s=([^,]+),([^,]+),(.+)"
)
LOCATION 's3://jackson-nifi-plc-data-1/2019-12-12/'
TBLPROPERTIES ('has_encrypted_data'='false')

抱歉,如果正则表达式没有正确转义,我只是把它输入堆栈溢出。
此表有四列,对应于每行中的四个字段。我已经命名了 ns 以及 s 从数据中,以及 v 对于数值,以及 dt 日期。日期需要以字符串的形式输入,因为它不是雅典娜本就理解的格式。
假设 ns 是一个记录标识符,然后您可以创建一个视图,该视图以不同值的行为轴 s 到列。你必须按照你想要的方式来做,下面当然只是一个示范:

CREATE VIEW my_pivoted_data AS
WITH data_aggregated_by_ns AS (
  SELECT
    ns,
    map_agg(array_agg(s), array_agg(v)) AS s_and_v
  FROM my_data
  GROUP BY ns
)
SELECT
  ns,
  element_at(s_and_v, 'A_EREG.A_EREG.A_PHASE_PRESSURE') AS phase_pressure,
  element_at(s_and_v, 'A_EREG.A_EREG.A_PHASE_REF_SIGNAL_TO_VALVE') AS phase_ref_signal_to_valve,
  element_at(s_and_v, 'A_EREG.A_EREG.A_PHASE_SEC_CURRENT') AS phase_sec_current,
  element_at(s_and_v, 'A_EREG.A_EREG.A_PHASE_SEC_VOLTAGE') AS phase_sec_voltage,
  element_at(s_and_v, 'A_EREG.A_EREG.ACTIVE_PWR') AS active_pwr
FROM data_aggregated_by_ns

如果上面的sql中有语法错误,我们深表歉意。
这样做的目的是创建一个视图(但首先尝试将其作为一个查询使用 WITH 它有两个部分。
第一部分,第一部分 SELECT 结果行聚合所有 s 以及 v 每个值的值 ns 在Map上。尝试单独运行此查询以查看结果的外观。
第二部分,第二部分 SELECT 使用第一部分的结果,只挑选不同的 v 多个值的值 s 我用聚合图从你的问题中选择的。

相关问题