我们的目标是利用PIG进行服务器日志的大规模日志分析。我需要从文件中加载PIG map数据类型。
我尝试使用以下数据运行示例PIG脚本。
我的CSV文件中名为'test'的行(由PIG处理)看起来像
151364,[ref#R813,highway#secondary]
我的PIG脚本
a = LOAD 'test' using PigStorage(',') AS (id:INT, m:MAP[]);
DUMP a;
想法是将int和第二个元素作为hashmap加载。 但是,当我转储时,int字段被正确解析(并在转储中打印)但是map字段没有被解析导致解析错误。
有人可以解释一下我是否遗漏了什么?
答案 0 :(得分:1)
我认为存在与分隔符相关的问题(例如,字段分隔符会以某种方式影响地图字段的分析,或者与地图分隔符混淆)。
使用此输入数据时(通知我使用分号作为字段分隔符):
151364;[ref#R813,highway#secondary]
下面的是我的grunt shell的输出:
grunt> a = LOAD '/tmp/temp2.txt' using PigStorage(';') AS (id:int, m:[]);
grunt> dump a;
...
(151364,[highway#secondary,ref#R813])
grunt> b = foreach a generate m#'ref';
grunt> dump b;
(R813)
答案 1 :(得分:1)
Atlast,我发现了问题所在。只需将去限制器从','更改为另一个字符,例如管道。字段分隔符与用于地图的分隔符','混淆:)
The string 151364,[ref#R813,highway#secondary] was getting parsed into,
field1: 151364 field2: [ref#R813 field3: highway#secondary]
Since '[ref#$813' is not a valid map field, there is a parse error.
我还查看了PigStorage函数的源代码并确认了解析逻辑 - Source code
@Override
public Tuple getNext() throws IOException {
for (int i = 0; i < len; i++) {
//skipping some stuff
if (buf[i] == fieldDel) { // if we find delim
readField(buf, start, i); //extract field from prev delim to current
start = i + 1;
fieldID++;
}
}
}
因此,由于PIG通过分隔符拆分字段,因此会导致字段的解析与用于映射的分隔符混淆。