Apache pig Pig拉丁语-从chararray line中提取满足两种不同过滤标准的字段,并在袋中分组

Apache pig Pig拉丁语-从chararray line中提取满足两种不同过滤标准的字段,并在袋中分组,apache-pig,Apache Pig,我不熟悉拉丁语。 我想从日志文件中提取与筛选条件匹配的所有行(有一个单词“line_token”),然后从这些匹配行中提取满足两个单独字段匹配条件的两个不同字段。由于行的结构不好,我将它们作为字符数组加载。 当我尝试运行以下代码时,我得到一个错误 “无效的资源架构:包架构的字段必须为元组” 我曾尝试对元组执行显式转换,但这不起作用 input_lines = LOAD '/inputdir/' AS ( line:chararray); filtered_lines = FILTER inpu

我不熟悉拉丁语。 我想从日志文件中提取与筛选条件匹配的所有行(有一个单词“line_token”),然后从这些匹配行中提取满足两个单独字段匹配条件的两个不同字段。由于行的结构不好,我将它们作为字符数组加载。 当我尝试运行以下代码时,我得到一个错误 “无效的资源架构:包架构的字段必须为元组” 我曾尝试对元组执行显式转换,但这不起作用

input_lines = LOAD '/inputdir/' AS ( line:chararray);

filtered_lines = FILTER input_lines BY (line MATCHES  '.*line_token1.*' );

tokenized_lines = FOREACH filtered_lines GENERATE FLATTEN(TOKENIZE(line)) AS tok_line;

my_wordbag = FOREACH tokenized_lines {
     word1 = FILTER tok_line BY ( $0 MATCHES  '.*word_token1.*'  ) ;
     word2 = FILTER tok_line BY ( $0 MATCHES  '.*word_token1.*' ) ;
     GENERATE word1 , word2 as my_tuple ;
  -- I also tried --> GENERATE (word1 , word2) as my_tuple ;
    }

dump my_wordbag;
我想我采取了一种非常错误的方法。 请注意-我的日志结构不好-因此我无法修复加载方式 对感兴趣的行进行后期加载和初始筛选(这很简单)——我想我需要做一些不同的事情,而不是对行进行标记并遍历字段以试图找到字段。 或者我应该使用连接

另外,如果我事先知道行的结构以及所有文本字段,那么以不同方式加载它(而不是作为字符)会使问题变得更容易吗

现在我做了一个折衷——我在原来的行过滤器中添加了一个额外的过滤器子句,并决定只从行中选择一个字段。当我回到它的时候,我会尝试连接并发布代码…-这是我的工作代码,它为我提供了有用的输出,但不是我想要的全部

-- read input lines from poorly structured log
input_lines = LOAD '/log-in-dir-in-hdfs' AS ( line:chararray) ;

-- Filter for line filter criteria and date interested in passed as arg
filtered_lines = FILTER input_lines BY (
       ( line MATCHES  '.*line_filter1*' )
       AND ( line MATCHES '.*line_filter2.*' )
       AND ( line MATCHES '.*$forDate.*' )
       ) ;

-- Tokenize every line
tok_lines = FOREACH filtered_lines
        GENERATE TOKENIZE(line) AS tok_line;

-- Pick up specific field frm tokenized line based on column filter criteria
fnames =   FOREACH tok_lines  {
        fname = FILTER tok_line BY ( $0 MATCHES  '.*field_selection.*' ) ;
        GENERATE FLATTEN(fname) as nnfname;
        }
-- Count occurances of that field and store it with field name 
-- My original intent is to store another field name as well 
-- I will do that once I figure how to put both of them in a tuple 
flgroup    = FOREACH fnames
         GENERATE FLATTEN(TOKENIZE((chararray)$0)) as cfname;
grpfnames  = group flgroup by cfname;
readcounts = FOREACH grpfnames GENERATE COUNT(flgroup), group ;
STORE readcounts INTO '/out-dir-in-hdfs';

您必须引用别名,而不是列

因此:

word1和word2也将是别名,而不是列


您需要输出的外观如何?

据我所知,在展平操作之后,每行有一行(tok_行),您希望从每行中提取2个单词。REGEX_EXTRACT将帮助您实现这一点。我不是正则表达式专家,所以写正则表达式部分将由你决定

data = FOREACH tokenized_lines 
          GENERATE 
              REGEX_EXTRACT(tok_line, <first word regex goes here>) as firstWord,
              REGEX_EXTRACT(tok_line, <second word regex goes here>) as secondWord;
data=FOREACH标记化的\u行
生成
REGEX_EXTRACT(tok_行)作为第一个字,
REGEX_EXTRACT(tok_行)作为第二个字;

我希望这能有所帮助。

Michal,这不是我需要的。我不想过滤外袋-标记化的_线-这是一组线-使用FOREACH我已经检查了它的每个元素-我想过滤单独的线。为了回答你的问题,我的输出是两列(两个我感兴趣的单词-每一行匹配)Gaurav-非常感谢。然而,这并不能解决我的问题-因为过滤器允许我提取我需要的令牌…我的问题是将这两个字段分组到一个包中-当我尝试这样做时-我得到一个错误-“无效的资源模式:包模式必须有元组作为其字段”或基于我如何尝试在一个包中强制匹配两个字段的其他错误,元组或映射使用强制转换或类似的愚蠢行为好的,你试过使用TOTUPLE函数吗?您需要将字段传递给此函数,以便从这些字段中创建元组。e、 TOTUPLE(field1,field2,field3)。这听起来很有用-会尽量让你保持联系-谢谢!!:-)伟大的我很乐意再次帮助你。如果我的回答解决了你的问题,请在回答后标记。这有助于识别已回答与未回答的问题,并帮助我获得更多分数:)
data = FOREACH tokenized_lines 
          GENERATE 
              REGEX_EXTRACT(tok_line, <first word regex goes here>) as firstWord,
              REGEX_EXTRACT(tok_line, <second word regex goes here>) as secondWord;