您可以在 Hive 中使用自定义地图缩减功能。
具有以下内容:
add file /some/path/identity.pl;
add file /some/path/collect.pl;
from (
from trace_input
MAP id, lat, lon, ts
USING './identity.pl'
as id, lat, lon, ts
CLUSTER BY id) map_output
REDUCE id, lat, lon, ts
USING './collect.pl' as id, list
trace_input包含您的跟踪数据,如上所述:
create table trace_input(id string, lat string, lon string, ts string)
row format delimited
fields terminated by '\t'
stored as textfile ;
identity.pl是一个简单的脚本,用于转储每一行(也可以是一个仅选择 lat、long 字段的脚本):
#!/usr/bin/perl
while (<STDIN>) {
print;
}
collect.pl (此处为示例)是一个简单的脚本,它收集具有相同对象 id 的连续行,保存每行的其余部分,并转储出具有 id 和逗号分隔列表(制表符分隔符)的行。
cluster by子句将确保 reducer 获得收集脚本所需的正确排序的输入。
用户脚本的输出是制表符分隔的STRING列。
运行查询,将产生以下输出:
1 X11,X12,T11,X21,X22,T12,X31,X22,T13
2 X11,X12,T21,X21,X22,T22
您可以修改 map 脚本以限制列,和/或修改 reduce 脚本以添加结果或将 lat、lon 与 ts 等分开。
如果这种形式足够了,您可以通过在 reduce 之前添加插入来直接插入结果表:
from (
from trace_input
MAP id, lat, lon, ts
USING './identity.pl'
as id, lat, lon, ts
CLUSTER BY id) map_output
INSERT overwrite table trace_res
REDUCE id, lat, lon, ts
USING './collect.pl';
这些字段将根据需要从字符串字段转换以匹配 trace_res 的架构。
如果您像我一样使用集合类型,您还可以执行以下操作:
create table trace_res as
select sq.id, split(sq.list,",") from
(
from (
from trace_input
MAP id, lat, lon, ts
USING './identity.pl'
as id, lat, lon, ts
CLUSTER BY id) map_output
REDUCE id, lat, lon, ts
USING './collect.pl' as (id int, list string)
) sq;
创建表中的第二个字段将是所有 lat、lon、ts 的列表;但可能会有比这更复杂的表。