如何在Spark窗口函数中使用降序的orderby()?

时间:2016-07-25 16:21:44

标签: scala apache-spark apache-spark-sql spark-dataframe

我需要一个窗口函数,它按一些键(=列名称)进行分区,按另一个列名称进行排序,并返回前x行的行。

这适用于升序:

def getTopX(df: DataFrame, top_x: String, top_key: String, top_value:String): DataFrame ={
    val top_keys: List[String] = top_key.split(", ").map(_.trim).toList
    val w = Window.partitionBy(top_keys(1),top_keys.drop(1):_*)
       .orderBy(top_value)
    val rankCondition = "rn < "+top_x.toString
    val dfTop = df.withColumn("rn",row_number().over(w))
      .where(rankCondition).drop("rn")
  return dfTop
}

但是当我尝试将其更改为第4行中的orderBy(desc(top_value))orderBy(top_value.desc)时,我收到语法错误。这里的正确语法是什么?

3 个答案:

答案 0 :(得分:32)

orderBy有两个版本,一个适用于字符串,另一个适用于Column个对象(API)。您的代码使用的是第一个版本,该版本不允许更改排序顺序。您需要切换到列版本,然后调用desc方法,例如myCol.desc

现在,我们进入API设计领域。传递Column参数的优点是你有更多的灵活性,例如,你可以使用表达式等。如果你想维护一个接受字符串而不是Column的API,您需要将字符串转换为列。有很多方法可以做到这一点,最简单的方法是使用org.apache.spark.sql.functions.col(myColName)

总而言之,我们得到了

.orderBy(org.apache.spark.sql.functions.col(top_value).desc)

答案 1 :(得分:1)

例如,如果我们需要在Window函数中按降序对名为Date的列进行排序,请在列名之前使用$符号,这将使我们能够使用{{ 1}}或asc语法。

desc

在用双引号指定列名之后,给Window.orderBy($"Date".desc) 降序排列。

答案 2 :(得分:0)

Selector('div.category-tree-node').withExactText('test1234').find('.cl-folder-list-element-arrow')