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

Hadoop 使用Pig将非结构化数据转换为结构化数据,hadoop,apache-pig,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 (Nov,1,18:23:3

我正在尝试使用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
(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)
正如我们所看到的,数据没有正确地分开(如制表符或逗号),所以我尝试使用“\t”加载数据并转储到终端上

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

dump A;

Store A into '\root\output';
输出:

Nov 1 18:23:34, 03 , 000, 198.0.13.24, 68.67.0.14, 99, 213, 5
(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
(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)加载数据,并执行了标记化,但无法实现目标

我还需要一些建议:

  • 因为我存储了3个字段,分别是月:“11”、日“1”和时间:“18:23:34”。是否可以将所有三个字段作为时间加入:“11月1日18:23:34”

  • 所有存储有dev_id=03、user_id=000等信息的数据,但我需要删除这些信息并存储03000198.0.13.24等信息

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

    编辑:1 在得到评论后,我尝试了对单个列使用REGEX_EXTRACT,效果很好。对于多列,我尝试了REGEX_EXTRACT_,如下所示:

    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提取多个字段。

    只需为您的数据编写一个自定义加载程序,您的所有问题都可以用java轻松解决。 我们可以找到一步一步地这样做的例子

    因为我存储了3个字段,分别是月:“11”、日“1”和时间:“18:23:34”。是否可以将所有三个字段作为时间加入:“11月1日18:23:34”

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


    所有存储有dev_id=03、user_id=000等信息的数据,但我需要删除这些信息并存储03000198.0.13.24等信息

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

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

    其他一些选择:

    • 编写自己的自定义Java存储函数以在Java中进行解析
    • 编写UDF(python、java等)来执行上述操作,而不是
      REGEX\u EXTRACT
      和嵌套的
      CONCAT
    • 将整个行作为一个字符加载,然后将其传递到执行所有解析的UDF中,并返回结果。此UDF被放入一个
      FOREACH
      。与编写自定义存储函数相比,我更喜欢它,因为我认为它更容易一些
    • *
    感谢您分享此链接。将尝试编写用于定制的java程序。感谢@Donald分享有用的信息。当我尝试使用单列正则表达式时,效果很好。对于多个列,我尝试了REGEX_EXTRACT_ALL(dev_id、user_id、int_ip、ext_ip、src、dest、response,“^.*=(.*)$”),但没有。另一种方法是,我尝试将数据作为单个字段加载,然后进行标记化,但仍然会出错。我已经添加了有问题的解释。你必须单独做。每列一个
    REGEX\u EXTRACT
    。多列不可能吗?内置功能。我尝试将所有样本数据加载为chararray,然后再加载REGEX_EXTRACT_all('value','(^.*=(.*)$);但得到了空输出。不。这不是pig的工作方式。
    REGEX_EXTRACT(field1,'REGEX')、REGEX_EXTRACT(field2,'REGEX')),…
    非常感谢您的建议,对于单列,它工作得非常完美。我还需要一个关于连接提取字段的建议。因为我们可以提取每个字段并存储在字段1的a、字段2的B等中。我们如何连接所有这些字段,至于连接转换,我们需要一个匹配的列,但每个字段中只有一列领域