PIG:标量在输出中有多于一行

PIG: scalar has more than one row in the output

我在 pig 中有以下代码,我在其中检查存储在记录中的主文件中的字段(记录中的 srcgt 和 destgt)是否具有另一个文件(intlgt.txt)中提到的值 [=12] =] 但它会抛出如下所述的错误。您能否建议如何在 Apache Pig 版本 0.15.0 (r1682971) 上克服此问题。

猪码:

record = LOAD '/u02/20160201*.SMS' USING PigStorage('|','-tagFile') ;
intlgtrec = LOAD '/u02/config/intlgt.txt' ; 
intlgt = foreach intlgtrec generate [=10=] as intlgt;
cdrfilter = foreach record generate (chararray)  as aparty, (chararray)  as bparty,(chararray)  as dt,(chararray) as timestamp,(chararray)  as status,(chararray)  as srcgt,(chararray)  as destgt,(chararray)[=10=] as cdrfname ,(chararray)  as prepost;
intlcdrs = FILTER cdrfilter by ( STARTSWITH(srcgt,intlgt::intlgt) or STARTSWITH(destgt,intlgt::intlgt) ) ;` 

错误是:

WARN  org.apache.hadoop.mapred.LocalJobRunner - job_local1939982195_0002
java.lang.Exception: org.apache.pig.backend.executionengine.ExecException:   ERROR 0: Scalar has more than one row in the output. 1st : (338), 2nd :(918299)  (common cause: "JOIN" then "FOREACH ... GENERATE foo.bar" should be "foo::bar") at org.apache.hadoop.mapred.LocalJobRunner$Job.runTasks(LocalJobRunner.java:462) at org.apache.hadoop.mapred.LocalJobRunner$Job.run(LocalJobRunner.java:522)

当您使用

intlcdrs = FILTER cdrfilter by ( STARTSWITH(srcgt,intlgt::intlgt) or STARTSWITH(destgt,intlgt::intlgt) );

PIG 正在寻找标量。无论是数字还是字符数组;但是一个。所以 pig 假设你的 intlgt::intlgt 是与一行的关系。例如

的结果
intlgt = foreach (group intlgtrec all) generate COUNT_STAR(intlgtrec.[=11=]) 

(这将生成单行,原始关系中的记录数)

在你的例子中,intlgt 包含不止一行,因为你还没有对它进行任何分组。 根据您的代码,您正在尝试查找两端都有 intlgt 的 SMS 消息。可能的解决方案:

  1. 如果您的 intlgt 条目都具有相同的长度(例如 3),则生成子字符串(srcgt, 1, 3)作为 srcgtsshort,并加入 intlgt::intlgt 和 record::srcgtshort。这将为您提供 srcgt 以 intlgt 中的值开头的记录。然后为 destgt.

  2. 重复此操作
  3. 如果它们的长度较少(例如,有些条目的长度为 3,有些长度为 4,有些长度为 5)你可以做同样的事情,但会更费力(因为每个 'length' 都需要一个字段)。

  4. 如果两个关系中的行数不是太大,则在它们之间做一个交叉,这将创建记录行和intlgt行的所有可能组合。然后你可以通过STARTSWITH(srcgt, intlgt::intlgt)来过滤,因为他们两个是同一个关系的字段。当心这种方法,因为记录的数量会变得巨大!