在Spark中使用窗口函数

时间:2016-03-23 06:39:26

标签: apache-spark apache-spark-sql window-functions

我正在尝试在Spark数据框中使用rowNumber。我的查询在Spark shell中按预期工作。但是当我在eclipse中编写它们并编译一个jar时,我面临一个错误

 16/03/23 05:52:43 ERROR ApplicationMaster: User class threw exception:org.apache.spark.sql.AnalysisException: Could not resolve window function 'row_number'. Note that, using window functions currently requires a HiveContext;
org.apache.spark.sql.AnalysisException: Could not resolve window function 'row_number'. Note that, using window functions currently requires a HiveContext;

我的疑问

import org.apache.spark.sql.functions.{rowNumber, max, broadcast}
import org.apache.spark.sql.expressions.Window
val w = Window.partitionBy($"id").orderBy($"value".desc)

val dfTop = df.withColumn("rn", rowNumber.over(w)).where($"rn" <= 3).drop("rn")

我在Spark shell中运行查询时没有使用HiveContext。当我运行与jar文件相同时,不确定为什么它会返回错误。如果有帮助的话,我也在Spark 1.6.0上运行脚本。有没有人面临类似的问题?

2 个答案:

答案 0 :(得分:9)

我之前已经回答了similar question。错误消息显示全部。随着 spark&lt;版本2.x ,您的应用程序jar中需要HiveContext,无其他方法。

您可以进一步了解SQLContextand HiveContext here之间的区别。

SparkSQL有一个SQLContext和一个HiveContextHiveContextSQLContext的超集。 Spark社区建议使用HiveContext。您可以看到,当您运行spark-shell(您的交互式驱动程序应用程序)时,它会自动创建一个定义为sc的SparkContext和一个定义为HiveContext的{​​{1}}。 sqlContext允许您执行SQL查询以及Hive命令。

您可以尝试检查HiveContext内的内容:

spark-shell

通过继承,Welcome to ____ __ / __/__ ___ _____/ /__ _\ \/ _ \/ _ `/ __/ '_/ /___/ .__/\_,_/_/ /_/\_\ version 1.6.0 /_/ Using Scala version 2.10.5 (Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0_74) scala> sqlContext.isInstanceOf[org.apache.spark.sql.hive.HiveContext] res0: Boolean = true scala> sqlContext.isInstanceOf[org.apache.spark.sql.SQLContext] res1: Boolean = true scala> sqlContext.getClass.getName res2: String = org.apache.spark.sql.hive.HiveContext 实际上是HiveContext,但反过来却不是这样。如果您更了解SQLContextHiveContext继承的内容,您可以查看source code

spark 2.0 以来,您只需创建一个SQLContext(作为单一入口点)即可消除SparkSession / HiveContext混淆问题

答案 1 :(得分:2)

对于Spark 2.0,建议使用SparkSession作为单一入口点。它消除了HiveContext / SqlContext混淆问题。

import org.apache.spark.sql.SparkSession
val session = SparkSession.builder
    .master("local")
    .appName("application name")
    .getOrCreate()

查看此databricks article了解如何使用它。