Apache spark full outer join - 过滤并选择可选字段

时间:2015-06-17 12:24:22

标签: join apache-spark apache-spark-sql rdd

我正在尝试使用完全外连接加入两个JavaPairRDD。我想要结合过滤器(如sql中的where子句)并且还只选择一个rdd(基于某些条件的左侧rdd或右侧rdd)。我已经尝试在连接结果rdd上做一个过滤函数,但它似乎不支持转换就像只选择一个rdd的函数。使用mapToPair,它不允许我过滤。我应该尝试做一个过滤器然后映射(反之亦然),做两次传递数据。我会想到一个直接的完全外连接函数支持来公开过滤器和映射。

JavaPairRDD<String, Tuple2<Optional<MyData>, Optional<MyDate>>> bagrp = agrp.fullOuterJoin(agrp);
JavaPairRDD<String, MyData> outmap = fgrp.mapToPair(new PairFunction <Tuple2<String, Tuple2<Optional<MyData>, Optional<MyData>>>,  String, MyData>() 
{
    @Override
    public Tuple2<String, MyData> call(Tuple2<String, Tuple2<Optional<MyData>, Optional<MyData>>> arg0) throws Exception 
        {
            if ( based on some condition ) return new Tuple2<String, MyData>(obj1,obj2);
            else return null;
        }
}

在mapToPair中返回null仍然存在于返回的RDD中。有没有办法避免,没有做一个明确的过滤器?

由于 Srivatsan

2 个答案:

答案 0 :(得分:0)

当您不想要包含任何内容时,可以使用flatMapToPair并返回空迭代器,当您想要生成元素时,可以使用单个元素返回迭代器。

答案 1 :(得分:0)

根据经验,最好先进行投影和过滤,以便减少群集周围的数据。我建议先关注并过滤,然后再进行加入。数据不会有两次传递,它会进行过滤。

更具体的答案取决于您的用例的详细信息。如果您的RDD已使用相同的分区程序(重新分区方法)进行分区,则可以进行连接,然后进行过滤,因为两个RDD的相同密钥已经位于相同的节点上。

之后你做mapToPair。如果你改变对的密钥,问题就不清楚了。如果不这样做,那么使用mapValues方法会更好,因为它会保留分区,这可能对下一步有用。