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 消息。可能的解决方案:
如果您的 intlgt 条目都具有相同的长度(例如 3),则生成子字符串(srcgt, 1, 3)作为 srcgtsshort,并加入 intlgt::intlgt 和 record::srcgtshort。这将为您提供 srcgt 以 intlgt 中的值开头的记录。然后为 destgt.
重复此操作
如果它们的长度较少(例如,有些条目的长度为 3,有些长度为 4,有些长度为 5)你可以做同样的事情,但会更费力(因为每个 'length' 都需要一个字段)。
如果两个关系中的行数不是太大,则在它们之间做一个交叉,这将创建记录行和intlgt行的所有可能组合。然后你可以通过STARTSWITH(srcgt, intlgt::intlgt)来过滤,因为他们两个是同一个关系的字段。当心这种方法,因为记录的数量会变得巨大!
我在 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 消息。可能的解决方案:
如果您的 intlgt 条目都具有相同的长度(例如 3),则生成子字符串(srcgt, 1, 3)作为 srcgtsshort,并加入 intlgt::intlgt 和 record::srcgtshort。这将为您提供 srcgt 以 intlgt 中的值开头的记录。然后为 destgt.
重复此操作
如果它们的长度较少(例如,有些条目的长度为 3,有些长度为 4,有些长度为 5)你可以做同样的事情,但会更费力(因为每个 'length' 都需要一个字段)。
如果两个关系中的行数不是太大,则在它们之间做一个交叉,这将创建记录行和intlgt行的所有可能组合。然后你可以通过STARTSWITH(srcgt, intlgt::intlgt)来过滤,因为他们两个是同一个关系的字段。当心这种方法,因为记录的数量会变得巨大!