【问题标题】:Extracting Key:Value from column fields in Hive从 Hive 的列字段中提取键:值
【发布时间】:2015-02-22 14:13:02
【问题描述】:

我目前正在学习/测试 Hive,但似乎无法找到适合此问题的解决方案: 我有如下所示的日志文件:

IP, Date, Time, URL, Useragent

我目前在包含这些列的表中。这些列由 '\t' 分隔,但已为 URL 提供了一些特定的客户端信息,看起来有点像这样:

example.org/log.gif?userID=xxx&sex=m&age=y&subscriber=y&lastlogin=ddd

我想用这些给定的值对创建一个新表:userID, sex, age, subscriber, lastlogin 另一个问题是值对并不总是完整的,或者有些缺失。像这样:

example.org/log.gif?userID=xxx&sex=m&age=y&subscriber=y&lastlogin=ddd

example.org/log.gif?userID=xxx&sex=m&age=y&lastlogin=

这使得 Hive 的 ... format delimited fields terminated by '&'; afaik 在这种情况下毫无用处,因为它会导致列中的值错误。

有没有办法在 Hive 中使用 SQL 和正则表达式解决这个问题?

【问题讨论】:

    标签: mysql sql regex hadoop hive


    【解决方案1】:

    这可以做到,尽管需要两个 Hive 表。您首先将数据加载到一个包含列的表中:

    IP, Date, Time, URL, Useragent
    

    这里我建议使用EXTERNAL Hive 表 - 您无需解析数据,而且此 Hive 表不需要存在很长时间,因此只需将 Hive 元数据放在其上即可:

    CREATE EXTERNAL TABLE raw_log (
      ip                string,
      date              string,
      time              string,
      url               string,
      useragent         string
    )
    LOCATION '<hdfs_location_of_the_raw_log_folder>';
    

    然后使用带有 Hive regexp_extract(string subject, string pattern, int index) 方法的 INSERT INTO 查询(请参阅 https://cwiki.apache.org/confluence/display/Hive/LanguageManual+UDF)将其加载到具有正确列的“最终”表中。

    您还可以编写自己的 UDF,这将使您能够更好地处理您提到的不完整/缺失值,尽管需要权衡每次输入数据格式时都必须重新编译和重新部署 JAR更改(请参阅https://cwiki.apache.org/confluence/display/Hive/HivePlugins)。

    【讨论】:

    • 我用一个表(userID)进行了尝试,并成功地插入了我的 raw_data 表中的所有用户 ID。但是,当我尝试将多个值插入新表 userdata(userID, age) 时出现错误:insert into table userdate regexp_extract(get userid), regexp_extract(get age) as userID,age from raw_data; 产生:FAILED: SemanticException [Error 10004]: Line 1:125 Invalid table alias or column reference 'age': (possible column names是:“来自 raw_data 的所有列”)
    • 那个方法接受三个参数,但是你只给了它一个,并且里面有一个空格。我不确定“get”来自哪里。我的正则表达式很差,所以我帮不上什么忙,但请查看我链接的 Hive UDF 页面以查看一些用法示例。
    • 对不起,我在那里使用了一些伪代码,我实际上给它三个参数并且正则表达式有效(目前认为不是 100% 正确)SQL 语法但似乎不正确.
    • 当然:INSERT INTO TABLE user_data SELECT regexp_extract(url, 'userID=(..........)', 0), regexp_extract(url, 'age=(..)', 0) AS userid,age FROM raw_data;
    • INSERT INTO TABLE user_data SELECT regexp_extract(url, 'userID=(..........)', 0) AS userid, regexp_extract(url, 'age=(..)', 0) AS age FROM raw_data; 会解决这个问题。
    猜你喜欢
    • 2019-02-27
    • 2020-10-06
    • 2021-12-29
    • 2021-09-26
    • 2021-09-17
    • 1970-01-01
    • 2020-01-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多