使用Pig将非结构化数据转换为结构化数据

时间:2013-08-28 13:45:11

标签: hadoop apache-pig

我正在尝试使用PIG构建非结构化数据以进行一些处理。

以下是数据样本:

Nov 1   18:23:34    dev_id=03   user_id=000 int_ip=198.0.13.24  ext_ip=68.67.0.14   src_port=99 dest_port=213   response_code=5

预期输出:

Nov 1 18:23:34, 03 , 000, 198.0.13.24, 68.67.0.14, 99, 213, 5

我们可以看到数据没有正确分隔(如制表符或逗号),所以我尝试使用'\ t'加载数据并转储到终端上。

A = LOAD '----' using PigStorage('\t') as (mnth: chararray, day: int, --------);

dump A;

Store A into '\root\output';

输出:

转储输出:

(Nov,1,18:23:34,dev_id=03,user_id=000,int_ip=198.0.13.24,ext_ip=68.67.0.14,src_port=99,dest_port=213,response_code=5)

存储oputut: 结果存储为与输入相同,而不是转储(逗号分隔)。

Nov 1   18:23:34    dev_id=03   user_id=000 int_ip=198.0.13.24  ext_ip=68.67.0.14   src_port=99 dest_port=213   response_code=5

替代方案:我还尝试使用DataStorage()作为(value:varchar)加载数据并执行TOKENIZE,但无法实现目标。

我需要更多建议:

  1. 由于我将3个字段存储为月份:“11月”,日:“1”,时间:“18:23:34”。是否有可能随着时间的推移加入所有三个领域:“11月1日18:23:34”。

  2. 使用dev_id = 03,user_id = 000等信息存储的所有数据,但我需要删除信息并存储03,000,198.0.13.24等信息。

  3. 是否可以使用PIG进行所有处理,或者我们需要编写MapReduce程序。

    编辑:1

    收到评论后,我尝试了单列的REGEX_EXTRACT,工作正常。对于多列,我尝试了REGEX_EXTRACT_ALL,如下所示:

    A = LOAD '----' using PigStorage('\t') as (mnth: chararray, day: int, dev: chararray, user: chararray --------);
    
    B = foreach A generate REGEX_EXTRACT_All(devid, userid, '(^.*=(.*)$) (^.*=(.*)$)');
    
    Dump B;
    

    我收到了错误:

    Error: ERROR org.apache.pig.tools.grunt.Grunt - ERROR 1070: Could not resolve REGEX_EXTRACT_All using imports.
    

    我们可以使用REGEX_EXTRACT_All提取多个字段。

2 个答案:

答案 0 :(得分:0)

只需为您的数据编写自定义加载程序,您就可以使用java轻松解决所有问题。 可以找到here

逐步执行该示例的示例

答案 1 :(得分:0)

  

我将3个字段存储为月份:“11月”,日:“1”,时间:“18:23:34”。是否有可能随着时间的推移加入所有三个领域:“11月1日18:23:34”。

您可以使用CONCAT连接FOREACH中的两个字符集。在这种情况下(这有点尴尬,也许有人可以提出一个不需要UDF的替代方案):

CONCAT(CONCAT(CONCAT(CONCAT(mnth, ' '), day), ' '), 'time')

  

所有数据都存储有dev_id = 03,user_id = 000等信息但我需要删除信息并存储03,000,198.0.13.24等信息。

你应该使用REGEX_EXTRACT这个,它提取一个给定正则表达式的文本。在FOREACH中使用它。构建一个正则表达式,在=之后抓取所有内容。在这种情况下:

REGEX_EXTRACT(field2, '^.*=(.*)$', 1);

其他一些选择:

  • 编写自己的自定义Java存储函数以在java中进行解析
  • 编写UDF(python,java等)以执行上述操作,而不是REGEX_EXTRACT和嵌套CONCAT
  • 将整个行作为一个chararray加载,然后将其传递给执行所有解析的UDF,并返回结果。这个UDF被放入FOREACH。我比编写自定义存储功能更喜欢这个,因为我认为它更容易一些。
  • *