开始更新啦

Spark SQL

        之前说过,SQl写得好,工作随便找。今天就从最开始的Spark SQL进行讲解,之后还会讲解一个项目,关于TMDB的一个Spark实验

创建DataFrame

        创建dataFrame的方法很多,之前的博客里面通过读取json文件进行创建DataFrame,今天用列表创建DataFrame。

//配置Spark 环境 
val spark = SparkSession.builder .master("local[1]") .appName("SparkByExamples.com") .getOrCreate() 
//创建数据 
val data = Seq(("James","Smith","USA","CA"),
 ("Michael","Rose","USA","NY"), 
("Robert","Williams","USA","CA"),
 ("Maria","Jones","USA","FL") ) 
//创建schema,就是所谓的表头,字段名
 val columns = Seq("firstname","lastname","country","state") 
import spark.implicits._ 
val df = data.toDF(columns:_*) 
df.show(false)

spark zhiding duilie spark指定队列_spark

        可以看到之前创建的columns作为了schema。为了验证这个猜想,下面打印一下schema

df.printSchema()

spark zhiding duilie spark指定队列_嵌套_02

选择单列和多列

        和我们用SQL一样,DSL中也是使用select进行查询。

        查询的api多个重载方法,下面来看一看

df.select("firstname","lastname").show() 
df.select($"firstname",$"lastname").show() 
df.select(df("firstname"),df("lastname")).show() 
//上面的三种方式是经常用到的,如果想要实现 name,age,age+1
 那么就需要使用$符号 

df.select("name","age",$"age" + 1).show()

        下面这一种是调用相关的包进行select。

import org.apache.spark.sql.functions.col df.select(col("firstname").alias("fname"),col("lastname")).show() 
//上面这个查询将字段名字进行改名,来看一下改名后的结果把

spark zhiding duilie spark指定队列_字段_03

 

选择所有列

第一种方法,直接*,最为方便

        df.select("*").show()

       第二种方法

        使用df.columns获取dataframe上的所有列,也就是Array[String],之后使用Map转换类型Array[Column].也就是将字段名包装到数组中。

val columnsAll = df.columns.map(m => col(m))
 df.select(columnsAll:_*).show()

选择前N列

  1. take

        //take返回的是数组,因此想要看到数据需要遍历打印出来         df.select("*").take(20).foreach(println(_))

spark zhiding duilie spark指定队列_sql_04

     2.map方法

df.select(df.columns.slice(0,2).map(m => col(m)):_*).show() 
//这里的slice不是限制的打印行数,限制的是打印列数 //(0,2) 打印的是前两列

spark zhiding duilie spark指定队列_嵌套_05

 按照位置或者索引打印列

从索引中打印列

df.select(df.columns(3)).show()

        按照索引位置,从0开始,0,1,2,3.这里只打印第四个列

       2.按照位置打印列

df.select(df.columns.slice(2,4).map(m => col(m)):_*).show()

        从下标为2开始,4之前结尾

选择嵌套结构列

        这是一个比较重要的内容,首先看一下嵌套的内容

spark zhiding duilie spark指定队列_spark_06

 

        如果将上面的内容当作dataframe。就会有三个大字段。在第一个大字段里面,嵌套了三个字段。

        

spark zhiding duilie spark指定队列_spark_07

        那么如何对上面的数据进行增加字段名呢?

        StructType结构类型,是所有StructField对象的集合。StructField就是字段的名称,类型。之后会在博客里面讲解StructField和StructType两个结构化类型。

import org.apache.spark.sql.types.{StringType, StructType} 
//使用Row对象进行嵌套 
val data2 = Seq(Row(Row("James","","Smith"),"OH","M"), 
Row(Row("Anna","Rose",""),"NY","F"),
 Row(Row("Julia","","Williams"),"OH","F"), 
Row(Row("Maria","Anne","Jones"),"NY","M"), 
Row(Row("Jen","Mary","Brown"),"NY","M"), 
Row(Row("Mike","Mary","Williams"),"OH","M") )
 //创建StructType,使用add方法增加每个字段的名字以及类型 
//即 StringType 字符串类型 
val schema = new StructType().add("name",new StructType().add("firstname",StringType) .add("middlename",StringType) .add("lastname",StringType)).add("state",StringType) .add("gender",StringType) 
//创建dataframe,第一个参数是RDD[Row],第二个参数是StructType 
val df2 = sparkSession.createDataFrame( sparkSession.sparkContext.parallelize(data2),schema) 
df2.printSchema() df2.show(false)

下面看一下,打印后的Schema把

spark zhiding duilie spark指定队列_嵌套_08

 

看一下数据

spark zhiding duilie spark指定队列_spark_09

        单独的展示name字段

        df2.select($"name").show()

spark zhiding duilie spark指定队列_spark_10

如果想要看嵌套字段name里面的特定列,可以明确的指定

        df2.select("name.firstname").show()

spark zhiding duilie spark指定队列_sql_11

        关于上面的内容,着重需要注意的就是后面的嵌套结构,因为在后面的TDMB项目中,会有嵌套的字段,就会需要到StructField和StructType。

碎碎念

        下午应该会该更新相关的内容,也就是StructField和StructType结构类型的相关知识。这篇博客中,应该重点看一下后面的嵌套字段。