2015-09-30 45 views
1

我有具有以下结构的平面文件:火花1.3.1将数据映射到键 - 值[]对在Java中

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

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

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

我会建议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。但是,您通常希望优于groupByKey,因为reduceByKey在洗牌数据前进行了地图边减少,而groupByKey则洗涤了所有内容。在你的特定情况下,你可能最终会洗掉相同数量的数据,因为你想要收集所有的值,但使用reduceByKey只是一个更好的习惯:)

+0

谢谢!工作很好! – Yustas

+0

很高兴听到它:)你可以把它标记为“已回答”吗? –

+0

np,如果能找到这个选项:) – Yustas