Spark在RDD的特定字段上生成排名

时间:2017-09-23 07:34:56

标签: scala apache-spark ranking

我已经得到rdd作为计算结果,让我们说它的格式如下:

(uid, factor, name, avatar, gender, otherFactor1, otherFactor2)

现在我希望RDD按factor排序并创建一个类似rank的字段,表示记录的等级,然后使用foreach将每条记录写入数据库

我知道可能通过以下方式执行此操作:

rdd.sortBy{
   case (uid, factor, name, avatar, gender, otherFactor1, otherFactor2) => {
       factor
   }
}.foreach{
   //how could I insert a rank field by the index of the loop?
}

在这里,我不知道如何通过foreach循环索引添加rank字段

任何想法?

2 个答案:

答案 0 :(得分:2)

如评论中所述,您可以使用

rdd.sortBy(_._2).zipWithIndex

您可以使用以下方法将其展平为更合理的结构:

rdd.sortBy(_._2).zipWithIndex.map { 
    case ((uid, factor, name, avatar, gender, otherFactor1, otherFactor2), rank) =>
    (uid, factor, name, avatar, gender, otherFactor1, otherFactor2, rank)
}

您可能需要注意zipWithIndex来自the source code for RDD.scala

的一件事
  

当此RDD包含多个分区时,此方法需要触发spark作业。

如果你想避免这种情况,你可以使用zipWithUniqueId,但我不认为它为每个元素提供连续的索引。

答案 1 :(得分:0)

看看下面是否有帮助。

case class ItemInfo(item:String, quantity:Int)
val data = sc.parallelize(List(("a",10),("b",20),("c",30)))
val ItemDF = data.map(x=> ItemInfo(x._1,x._2)).toDF()
ItemDF.registerTempTable("Item_tbl")
val rankedItems = sqlContext.sql("select item, quantity, rank() over(order by quantity desc) as rank from Item_tbl")
rankedItems.collect().foreach(println)

此示例根据数量对项目进行排名。