在引用列时(在这种情况下,在select语句中),我注意到两种不同的符号样式。两者在功能上有区别吗?
val df = spark.read.table("mytable").select('column1,'column2)
vs。
val df = spark.read.table("mytable").select($"column1",$"column2")
我找不到任何能真正解释差异或是否有标准的东西。
答案 0 :(得分:1)
使用'column1,'column2
或$"column1",$"column2"
中的任何一个时,返回值将是ColumnName(column1), ColumnName(column2)
,它恰好是Column()
的子类,是预期的子类之一键入select
。但是,它们的实现不同。
为了使用符号,导入import spark.implicits._
要包含在应用程序中,其中spark
是SparkSession
对象。导入可确保以下隐式内容可用且在范围内。
通过Spark代码
@Experimental
object implicits extends SQLImplicits with Serializable {
protected override def _sqlContext: SQLContext = SparkSession.this.sqlContext
}
spark.implicits
扩展了SQLImplicits
package org.apache.spark.sql
abstract class SQLImplicits extends LowPrioritySQLImplicits {
...
/**
* Converts $"col name" into a [[Column]].
*
* @since 2.0.0
*/
implicit class StringToColumn(val sc: StringContext) {
def $(args: Any*): ColumnName = {
new ColumnName(sc.s(args: _*))
}
}
...
/**
* An implicit conversion that turns a Scala `Symbol` into a [[Column]].
* @since 1.3.0
*/
implicit def symbolToColumn(s: Symbol): ColumnName = new ColumnName(s.name)
}
使用$column1
时,将调用隐式类$
中的StringToColumn
方法,该方法将String
转换为ColumnName
实例。
'
是scala符号。为了使用它,import spark.implicits._
不是必需的。但是,要将Scala符号转换为Column
,需要导入。使用此符号时,隐式方法symbolToColumn
将被执行并返回一个ColumnName
实例。请注意,'column1
与Scala中的Symbol("column1")
相同。
在org.apache.spark.sql.Column.scala
中,ColumnName
是Column
的子类。因此从$
和'
返回的对象可以在DataFrame / Dataset select
方法中使用。
/**
* A convenient class used for constructing schema.
*
* @since 1.3.0
*/
@InterfaceStability.Stable
class ColumnName(name: String) extends Column(name) {
...
}