在 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 提取时间戳的每个部分作为单独的列,并在查询中将它们与分隔符正确连接以获得正确的时间戳格式,但这不会给您带来任何改进,因为无论如何您都需要额外的查询中的转换。
我有一个如下所示的文件:
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 提取时间戳的每个部分作为单独的列,并在查询中将它们与分隔符正确连接以获得正确的时间戳格式,但这不会给您带来任何改进,因为无论如何您都需要额外的查询中的转换。