我正在尝试使用单个字段创建包含分区的配置单元表。我想要处理的数据是日志数据。日志格式为:
DATE TIME IPAddress HTTP_METHOD MESSAGE
创建表格配置单元查询:
CREATE EXTERNAL TABLE test_Part(
logdate string,
logtime string,
ip string,
message string)
PARTITIONED BY(method string)
ROW FORMAT SERDE 'org.apache.hadoop.hive.serde2.RegexSerDe'
WITH SERDEPROPERTIES (
"input.regex" = "(\\d{4}-\\d{2}-\\d{2})\\s(\\d{2}:\\d{2}:\\d{2})\\s(\\d+\\.\\d+\\.\\d+\\.\\d+)\\s(\\S+)\\s(.*$)",
"output.format.string" = "%1$s %2$s %3$s %5$s %4$s"
)
STORED AS TEXTFILE;
并加载脚本:
LOAD DATA LOCAL INPATH '/home/user/tools/apache-hive-1.2.2-bin/scripts/sample1.log' OVERWRITE INTO TABLE test_Part PARTITION(method='GET');
当我在上面的表上运行一个select查询时,它会给出错误消息
异常失败 产生java.io.IOException:org.apache.hadoop.hive.serde2.SerDeException: 匹配组的数量与列数不匹配
我缺少什么?
答案 0 :(得分:0)
应该是4组,因为表DDL中有4列。你的正则表达式有5组。 method
是一个分区(带文件的目录),该列通常不存在于文件本身中,您无需在正则表达式中指定它。
分区存储为包含分区位置和键值的元数据。 位置看起来像table_dir / method = GET /
在此处查看好的示例: http://www.dowdandassociates.com/blog/content/howto-use-hive-with-apache-logs/
如果文件中也存在分区列,则应该向表定义添加更多列。似乎列存在。是HTTP_METHOD吗?然后在消息列之前简单地再添加一列HTTP_METHOD并再次检查你的regexp。
答案 1 :(得分:0)
分区反映了一种情况,即可以直接访问以特定值(分区列值)为特征的行,而无需访问其他不必要的数据。
这显然不是这种情况,因此您无法在数据文件上声明分区表。
从这一点开始,您可以执行以下操作:
省略分区。
CREATE EXTERNAL TABLE test_Part_stg(
logdate string,
logtime string,
ip string,
method string,
message string)
ROW FORMAT SERDE 'org.apache.hadoop.hive.serde2.RegexSerDe'
WITH SERDEPROPERTIES (
"input.regex" = "(\\d{4}-\\d{2}-\\d{2})\\s(\\d{2}:\\d{2}:\\d{2})\\s(\\d+\\.\\d+\\.\\d+\\.\\d+)\\s(\\S+)\\s(.*$)"
)
STORED AS TEXTFILE;
创建一个额外的分区表,并使用上一步中的表填充它。
(此表存储不必是TEXTFILE)
CREATE EXTERNAL TABLE test_Part(
logdate string,
logtime string,
ip string,
message string)
PARTITIONED BY(method string)
STORED AS TEXTFILE;
set hive.exec.dynamic.partition.mode=nonstrict
;
insert into test_Part partition (method)
select logdate,logtime,ip,message,method
from test_Part_stg
;
或
insert into test_Part partition (method) (logdate,logtime,ip,method,message)
select *
from test_Part_stg
;
output.format.string
已弃用,它未在RegexSerDe中定义,并且没有任何其他未定义的SerDe参数的功能含义。