reduceBykey Spark维持秩序

时间:2015-08-05 21:45:43

标签: scala apache-spark rdd reduce

我的输入数据集看起来像

id1, 10, v1
id2, 9, v2
id2, 34, v3
id1, 6, v4
id1, 12, v5
id2, 2, v6

我希望输出

id1; 6,v4 | 10,v1 | 12,v5
id2; 2,v6 | 9,v2 | 34,v3

这就是

id1: array[num(i),value(i)] where num(i) should be sorted

我尝试过:

  • 获取id和第二列作为键sortByKey,但由于它是一个字符串, 排序不像int那样发生,而是作为字符串

  • 发生
  • 获取第二列作为键sortByKey,然后获取id和key以及第二列 值列reduceByKey。但在这种情况下,在做的时候 reduceByKey;订单不会保留。即使groupByKey也没有阻止 命令。实际上这是预期的。

任何帮助将不胜感激。

1 个答案:

答案 0 :(得分:8)

由于您没有提供有关输入类型的任何信息,我认为它是RDD[(String, Int, String)]

val rdd = sc.parallelize(
    ("id1", 10, "v1") :: ("id2", 9, "v2") ::
    ("id2", 34, "v3") :: ("id1", 6, "v4") :: 
    ("id1", 12, "v5") :: ("id2", 2, "v6") :: Nil)

rdd
  .map{case (id, x, y) => (id, (x, y))}
  .groupByKey
  .mapValues(iter => iter.toList.sortBy(_._1))
  .sortByKey() // Optional if you want id1 before id2

修改

要获得您已描述in the comments的输出,您可以使用以下内容替换传递给mapValues的函数:

def process(iter: Iterable[(Int, String)]): String = {
  iter.toList
      .sortBy(_._1)
      .map{case (x, y) => s"$x,$y"}
      .mkString("|")
}