Apache pig ApachePig将整个关系加载到UDF中

Apache pig ApachePig将整个关系加载到UDF中,apache-pig,Apache Pig,我有一个猪的脚本,属于2个猪的关系,比如说a和B。a是一个小关系,B是一个大关系。我的UDF应该将所有A加载到每台机器的内存中,然后在处理B时使用它。目前我是这样做的 A = foreach smallRelation Generate ... B = foreach largeRelation Generate propertyOfB; store A into 'templocation'; C = foreach B Generate CustomUdf(propertyOfB); 然后

我有一个猪的脚本,属于2个猪的关系,比如说a和B。a是一个小关系,B是一个大关系。我的UDF应该将所有A加载到每台机器的内存中,然后在处理B时使用它。目前我是这样做的

A = foreach smallRelation Generate ...
B = foreach largeRelation Generate propertyOfB;
store A into 'templocation';
C = foreach B Generate CustomUdf(propertyOfB);
然后,我从“templocation”加载每台机器以获得A。这是可行的,但我有两个问题

  • 我的理解是我应该以某种方式使用HDFS缓存,但我不确定如何将关系直接加载到HDFS缓存中
  • 当我在我的UDF中重新加载文件时,我需要编写逻辑来解析从输出到文件的输出,而我更愿意直接使用包和元组(是否有内置的Pig java函数将字符串解析回包/元组形式?)

  • 有人知道应该怎么做吗?

    这里有一个技巧对你有用

    您首先对一个字段中的所有数据“打包”到一个字段中。然后在a和B上人为地添加一个公共字段,并将它们连接起来。这样,对于增强的B中的每个元组,您将拥有A的完整数据供您的UDF使用

    是这样的:

    (假设最初在A中有字段fa1、fa2、fa3,在B中有字段fb1、fb2)


    因为这是复制联接,所以它也是唯一的映射侧联接。

    A和B是否有可以进行联接的列?在这种情况下,是的,它们具有相同的数据,并且可以联接。我需要比较A的每一行和B的每一行。我想我可以做交叉连接,但那不是效率更低吗?我将比必要的时间多重新处理B A-1次,并且我将失去一次针对A的一行运行所有B行的能力,这是必需的。您可以发布一个输入和输出数据的示例吗?A:{id:chararray,attributes:{tuple\u of_tokens:(token:chararray)}C是一个由两个字段元组组成的包,其中第一个字段是a的id,第二个字段是一个元组,包含a的前N个B。我希望有一个通用的解决方案。。这不是我需要在UDF中存储先前pig结果的唯一位置。如果您可以在id列上执行联接,那么您就可以使用用户复制联接,这是一种映射侧联接。J=通过(id)连接B,通过(id)连接A作为“复制”;apachepig将在每个数据节点上加载一个in缓存。而不是将J传递给UDF,我认为这将在Map阶段进行,因此将是有效的。我认为我目前的解决方案是只在HDFS中保存A,然后将其加载到所有的还原器中,这比使用笛卡尔积更有效。我希望能找到一种非黑客的方式来完成这一切而不耍花招。对不起,我把a和B搞错了。我认为A是更大的关系,B是更小的关系。我已经更改了代码。我的代码根本不是笛卡尔积,它是唯一一个非常有效的映射端连接,并且您不必在您的UDF中读取/解析a(假设您想在本地模式下测试它,那么您的UDF将不起作用)。组都不是映射端,只有连接is@DexinWang不确定这是否真的有效。你测试过了吗?你有推荐人吗?
    -- add an artificial join key with value 'xx'
    B_aux = FOREACH B GENERATE 'xx' AS join_key, fb1, fb2;
    A_all = GROUP A ALL;
    A_aux = FOREACH A GENERATE 'xx' AS join_key, $1;
    A_B_JOINED = JOIN B_aux BY join_key, A_aux BY join_key USING 'replicated';
    
    C = FOREACH A_B_JOINED GENERATE CustomUdf(fb1, fb2, A_all);