Spark 1.3.1将数据映射到Java中的key-value []对

时间:2015-09-30 08:17:11

标签: apache-spark mapping

我有平面文件,结构如下:

key1|"value-001"
key2|"value-002"
key2|"value-003"
key3|"value-004"
key2|"value-005"
key1|"value-006"
key3|"value-007"

我需要将此数据文件映射到键值对,其中value将是一个键的值列表,例如:

key1:["value-001","value-006"]
key2:["value-002","value-003","value-005"]
key3:["value-004","value-007"]

我需要从Java代码中执行此操作。正如我从Spark编程指南中所理解的那样,此操作应该由sc.flatMapValues(..)sc.flatMap(..)sc.groupByKey(..)实现,但我不知道哪一个。我该怎么做?

1 个答案:

答案 0 :(得分:1)

我建议reduceByKey :)此列表模仿您的输入:

List<String> input = Arrays.asList(
  new String[]{new String("key1|value-001"),
               new String("key2|value-002"),
               new String("key2|value-003"),
               new String("key3|value-004"),
               new String("key2|value-005"),
               new String("key1|value-006"),
               new String("key3|value-007")});

转换为rdd(您当然只需使用sc.textFile()读入您的文件)

JavaRDD<String> rdd = javaSparkContext.parallelize(input);

我们现在有一个字符串的RDD。以下映射到键值对(请注意该值将添加到列表中),然后reduceByKey将每个键的所有值组合到一个列表中,从而产生您想要的结果。

JavaPairRDD<String, List<String>> keyValuePairs = rdd.mapToPair(obj -> {
        String[] split = obj.split("|");
        return new Tuple2(split[0], Arrays.asList(new String[]{split[1]}));
    });

JavaPairRDD<String, List<String>> result = keyValuePairs.reduceByKey((v1, v2) -> {
        v1.addAll(v2);
        return v1;
    });

编辑:我觉得我应该提一下你也可以使用groupByKey。但是,您通常希望reduceByKey支持groupByKey而不是reduceByKey,因为groupByKey执行地图方面减少BEFORE后移动数据,而groupByKey会改变周围的一切。在您的特定情况下,由于您希望收集所有值,因此您可能最终会像使用reduceByKey一样随机播放相同数量的数据,但使用{{1}}只是一个更好的习惯: )