在 table 创建期间在 Hive 中解析时间戳

Parse timestamp in Hive during table creation

我有一个如下所示的文件:

33.49.147.163           20140416123526  https://news.google.com/topstories?hl=en-US&gl=US&ceid=US:en    29  409 Firefox/5.0

我想将它加载到配置单元中 table。我是这样做的:

create external table Logs (
    ip string,
    ts timestamp,
    request string,
    page_size smallint,
    status_code smallint,
    info string
)
row format serde 'org.apache.hadoop.hive.serde2.RegexSerDe'
with serdeproperties (
"timestamp.formats" = "yyyyMMddHHmmss",
"input.regex" = '^(\S*)\t{3}(\d{14})\t(\S*)\t(\S*)\t(\S*)\t(\S*).*$'
)
stored as textfile
location '/data/user_logs/user_logs_M';

select * from Logs limit 10;

结果

33.49.147.16 NULL https://news.google.com/topstories?hl=en-US&gl=US&ceid=US:en 29 409 Firefox/5.0

如何正确解析时间戳,避免出现 NULL?

"timestamp.formats" SerDe 属性 works only with LazySimpleSerDe (STORED AS TEXTFILE),它不适用于 RegexSerDe。如果您使用的是 RegexSerDe,则在查询中解析时间戳。

在 CREATE TABLE 中将 ts 列定义为 STRING 数据类型,并在查询中将其转换为如下所示:

select timestamp(regexp_replace(ts,'(\d{4})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})','-- ::.0')) as ts

当然,您可以使用 SerDe 提取时间戳的每个部分作为单独的列,并在查询中将它们与分隔符正确连接以获得正确的时间戳格式,但这不会给您带来任何改进,因为无论如何您都需要额外的查询中的转换。