我使用Hive进行空间数据库的批处理。我的跟踪表看起来像这样:
object | lat | long | timestamp
1 | X11 | X12 | T11
1 | X21 | X22 | T12
2 | X11 | X12 | T21
1 | X31 | X22 | T13
2 | X21 | X22 | T22
我想将每个对象的每个lat长度映射到一个数字(例如考虑地图匹配),但算法需要考虑许多相邻的数据点来获得结果。例如,我需要对象1的所有3个数据点将这3个数据点中的每一个映射到一个数字。无法逐个处理它们。
我正在考虑使用变换使用map-reduce和hive,但我不确定如何使用。有人可以帮帮我吗?
答案 0 :(得分:2)
您可以在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 (示例here)是一个简单的脚本,它收集具有相同对象ID的连续行,保存每行的剩余部分,并转储出一行id和逗号分隔列表(制表符分隔符)。
cluster by 子句将确保reducers获取collect脚本所需的正确排序输入。
用户脚本的输出以制表符分隔 STRING 列。
运行查询将产生以下输出:
1 X11,X12,T11,X21,X22,T12,X31,X22,T13
2 X11,X12,T21,X21,X22,T22
您可以修改地图脚本以限制列,和/或修改reduce脚本以添加结果或将lat,lon与ts分开等。
如果此表单足够,您可以通过在reduce之前添加 insert 直接插入结果表:
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的列表;但可能会有比这更复杂的表格。