【SparkSQL】扩展 ---- Column对象


目录:

    ​一、Column的无绑定创建方式

    ​二、Column的有绑定创建方式

    ​三、Column的操作:别名、转换

    ​四、Column的方法 API


一、Column的无绑定创建方式

1.单引号'在Scala中是一个特殊的符号,通过​'​,会生成一个Symbol对象,SymboL对象可以理解为是一个字符串的变种,但是比字符串的效率高很多,在Spark中,对Scala中的Symbol对象做了隐式转换,转换为一个ColumnName对象,ColumnName是CoLumn的子类,所以在Spark中可以如下去选中一个列

val ds = Seq(Person("Alice",19),Person("Jack",19),Person("Tom",18)).toDS()
val ds1 = Seq(Person("Alice",19),Person("Jack",19),Person("Tom",18)).toDS()
val df = Seq(("Alice",19),("Jerry",19),("Tom",18)).toDF("name","age")
// 1.‘  必须导入spark的隐式转换才能使用 str.intern()
// Symbol 对象类似于一种字符串,最终会通过转换变为column对象
val c1: Symbol = 'name

【SparkSQL】扩展 ---- Column对象_返回顶部


Symol对象在隐式转换中会被转成ColumnName,而ColumnName又是继承自Column的

【SparkSQL】扩展 ---- Column对象_spark_02

2.同理,$ 符号也是一个隐式转换,同样通过spark.implicits导入,通过 ​$​ 可以生成一个Column对象

// 2.$  必须导入spark的隐式转换才能使用
val c2: ColumnName = $"name"

【SparkSQL】扩展 ---- Column对象_返回顶部_03

3.SparkSQL提供了一系列的函数,可以通过函数实现很多功能在后面课程中会进行详细介绍,这些函数中有两个可以帮助我们创建Column对象,一个是col,另外一个是​colum​

// 3.col 必须导入functions
import org.apache.spark.sql.functions._
val c3: Column = col("name")
// 4.column 必须导入functions
val c4: Column = column("name")

以上四种创建方式,是否有关联的DataSet? 没有,都是独立的创建Column对象

  • 不仅DataSet可以,DataFrame也可以使用column对象选中行
    ds.select(c1).show()
    df.select(c2).show()
  • 【SparkSQL】扩展 ---- Column对象_返回顶部_04

  • Column 对象可以和命令式的弱类型的 API 配合使用,不仅select方法可以使用column对象,其他的方法也可以:
    df.where(c1 === “Jack”).show()
  • 【SparkSQL】扩展 ---- Column对象_spark_05

返回顶部


二、Column的有绑定创建方式

1.​Dataset.col 前面的 Column 对象创建方式所创建的 Column 对象都是 Free 的,也就是没有绑定任何Dataset,所以可以作用于任何Dataset,同时,也可以通过Dataset的col方法选择一个列,但是这个Colum是绑定了这个Dataset的,所以只能用于创建其的Dataset上

// 5.dataSet.col --- 有绑定的创建
// 使用该方法获取column对象,会和某个DataSet进行绑定,在逻辑计划中,就会有不同的表现
val c5 = ds.col("name")
val c6 = ds1.col("name")
.select(c6).show()  // 假如使用 ds 去调用绑定了 ds1 的 c6(Column对象),会报错
  • 进行了绑定的column对象只能由绑定的DataSet去调用
  • org.apache.spark.sql.AnalysisException:​​Resolved attribute(s) name#7 missing from name#2,age#3 in operator !​
  • Project [name#7]. Attribute(s) with the same name appear in the operation: name. Please check if the right attribute(s) are used.;;
  • !Project [name#7]
  • ± AnalysisBarrier
  • ± LocalRelation [name#2, age#3]

为什么要和dataset进行绑定?

  • 便于在进行连接的时候进行对应列的比较
    ​​ds.join(ds1,ds.col("name") === ds1.col("name"))

2.​Dataset.apply可以通过Dataset对象的apply方法来获取一个关联此Dataset的Colum 对象

// 6.dataset.apply
// 以下两种方式一样
val c7: Column = ds.apply("name")
val c8: Column = ds("name")

scala中的apply方法

如果一个对象中有apply方法,那么调用apply方法与直接调用该对象,效果一样!!!

返回顶部


三、Column的操作:别名、转换

  • as 起别名
  • 【SparkSQL】扩展 ---- Column对象_隐式转换_06


  • 【SparkSQL】扩展 ---- Column对象_返回顶部_07

  • as 数据类型转换 — 使用as利用泛型去规定转换的类型
  • 【SparkSQL】扩展 ---- Column对象_隐式转换_08

补充:

  • 数据类型的转换还经常使用cast
  • 【SparkSQL】扩展 ---- Column对象_返回顶部_09

返回顶部


四、Column的方法 API

【SparkSQL】扩展 ---- Column对象_spark_10


【SparkSQL】扩展 ---- Column对象_spark_11

返回顶部