如何根据值对scala.collection.Map [(String,String),Long]中的spark countByKey()结果进行排序?

时间:2017-06-20 05:43:24

标签: scala apache-spark

CSV表存储在位置" / user / root / sqoopImport / orders"

val orders = sc.textFile("/user/root/sqoopImport/orders")
orders.map(_.split(",")).map(x=>((x(1),x(3)),1)).countByKey().foreach(println)

这里我基于key(​​String,String)

得到了这个未排序的结果
((2014-03-19 00:00:00.0,PENDING),9)
((2014-04-18 00:00:00.0,ON_HOLD),11)
((2013-09-17 00:00:00.0,ON_HOLD),8)
((2014-07-10 00:00:00.0,COMPLETE),57)

我想排序,所以我尝试了

orders.map(_.split(",")).map(x=>((x(1),x(3)),1)).countByKey().sortBy(_._1).foreach(println)
<console>:30: error: value sortBy is not a member of scala.collection.Map[(String, String),Long]
              orders.map(_.split(",")).map(x=>((x(1),x(3)),1)).countByKey().sortBy(_._1).foreach(println)

3 个答案:

答案 0 :(得分:0)

这是因为  orders.map(_.split(",")).map(x=>((x(1),x(3)),1)).countByKey()

返回Map[(String, String),Long],其中我们无法应用sortBy()函数

你能做的是

    val result = orders.map(_.split(",")).
         map(x=>((x(1),x(3)),1)).countByKey().toSeq

    //and apply the sortby function in new RDD
    sc.parallelize(result).sortBy(_._1).collect().foreach(println)

希望这有帮助!

答案 1 :(得分:0)

countByKey()操作。它完成Spark计算并为您提供正常的Scala Map。由于Map是无序的,因此对其进行排序是没有意义的:您需要先使用Seq将其转换为toSeq。如果你想留在Spark land,你应该使用转换,在这种情况下reduceByKey()

orders.map(_.split(",")).map(x=>((x(1),x(3)),1)).reduceByKey(_ + _).sortBy(_._1).foreach(println)

另请注意,foreach(println)只能按照您在本地模式中的预期工作:https://spark.apache.org/docs/latest/programming-guide.html#printing-elements-of-an-rdd

答案 2 :(得分:0)

地图是无序集合。您需要将该映射转换为维护顺序并按键排序的集合。例如:

val sorted = map.toSeq.sortBy{
  case (key,_) => key
}