spark sql 官网示例

目录

         1.Dataset/Dataframe基本操作

2.RDD转Dataset/Dataframe

3.不同数据集


对于spark,无论core还是streaming,亦或sql,structed streaming

最好的资料就是官网示例+源码

本人的spark sql的学习路线是

1.官网示例(入门,了解)

2.Dataset/Dataframe的各个方法(了解之后才能在面对需求是知道哪个最合适)

3.关键的源码

本篇为第一步,官网示例,Dataset简称为ds,Dataframe简称为df

1.Dataset/Dataframe基本操作

def main(args: Array[String]): Unit = {
     val spark=SparkSession
      .builder()
      .appName("demo1")
      .master("local[*]")
      .getOrCreate()

    //用于隐式转换,将RDD转为DataFrame
    import spark.implicits._

    //读取json创建DataFrame,以下为json内容
    //{"name":"Michael"}
    //{"name":"Andy", "age":30}
    //{"name":"Justin", "age":19}
    val df=spark.read.json("C:\\zlq\\data\\people.json")
    
    df.show()//将json字段作为字段名
+----+-------+
| age|   name|
+----+-------+
|null|Michael|
|  30|   Andy|
|  19| Justin|
+----+-------+

    df.printSchema()//以树的形式打印schema,类型为推断出来的
root
 |-- age: long (nullable = true)
 |-- name: string (nullable = true)

     df.select($"name").show()//查询某列
+-------+
|   name|
+-------+
|Michael|
|   Andy|
| Justin|
+-------+

    df.select($"name",$"age"+1).show()//将age加1
+-------+---------+
|   name|(age + 1)|
+-------+---------+
|Michael|     null|
|   Andy|       31|
| Justin|       20|
+-------+---------+
    
    df.filter($"age">20).show()//查询年龄20以上的
+---+----+
|age|name|
+---+----+
| 30|Andy|
+---+----+

    df.groupBy($"age").count().show()//计算各个年龄的人数,null值会参与计算
+----+-----+
| age|count|
+----+-----+
|  19|    1|
|null|    1|
|  30|    1|
+----+-----+
    
    //以上是df的操作,接下来我们用sql的方式与df交互
    //创建全局临时视图,就是表名,默认库位global_temp
    df.createGlobalTempView("people")
    spark.sql("select * from global_temp.people").show()//查看所有
    +----+-------+
| age|   name|
+----+-------+
|null|Michael|
|  30|   Andy|
|  19| Justin|
+----+-------+

      //创建ds,跟rdd类似,有两种途径,一种df转,一种集合转
     val ds1=Seq(1,2,3).toDS()
     ds.show()
+-----+
|    2|
|    3|
|    4|
+-----+
        
      val peopleDS=spark.read.json("C:\\zlq\\data\\people.json").as[Person]//as将df转ds
      peopleDS.show()
+----+-------+
| age|   name|
+----+-------+
|null|Michael|
|  30|   Andy|
|  19| Justin|
+----+-------+ 
}
case class Person(name:String,age:Int)

2.RDD转Dataset/Dataframe

def main(args: Array[String]): Unit = {
    val spark=SparkSession
      .builder()
      .appName("demo2")
      .master("local[*]")
      .getOrCreate()
    import spark.implicits._

    //1.使用反射将RDD[Class]转为df
    val df=spark.sparkContext
      .textFile("C:\\zlq\\data\\people.txt")
      .map(_.split(","))
      .map(ele=>(Person(ele(0),ele(1).trim.toInt))).toDF()//toDF()转为DF
    
    df.createOrReplaceTempView("people")//创建临时视图
    val teendf=spark.sql("select name,age from people where age between 13 and 19")
    teendf.map(ele=>"name:"+ele(0)).show()//可以通过下标处理sql返回结果
    teendf.map(ele=>"name:"+ele.getAs[String]("name")).show()//也可以通过字段名处理
    
    //2.编程方式指定schema
    val schemaString="name age"//df字段名
    val fields=schemaString.split(" ")
        .map(ele=>StructField(ele,StringType,nullable = true))//返回Array[StructFiield]
    val schema=StructType(fields)
    
    val peopleRDD=spark.sparkContext.textFile("C:\\zlq\\data\\people.txt")
    val rowRDD=peopleRDD
      .map(_.split(","))
      .map(ele=>Row(ele(0),ele(1).trim)
    //将schema作用到rdd上
    val df=spark.createDataFrame(rowRDD,schema)
}
case class Person(name:String,age:Int)

3.不同数据集

官网说parquet挺多的,但我们用的是orc,所以就不在这多写了。

def main(args: Array[String]): Unit = {
    val spark=SparkSession
    .builder()
    .appName("demo_2")
    .master("local[*]")
    .getOrCreate()
    
    import spark.implicits._
    //读取json数据
    val peopleDF=spark.read.json("C:\\zlq\\data\\people.json")
    peopleDF.printSchema()
    peopleDF.createGlobalTempView("people")
    spark.sql("select * from global_temp.people where age between 13 and 19").show()
}

最后是用的最多的,hive数据源,之前写过篇配置spark sql查询hive的,有兴趣的可以看看

def main(args: Array[String]): Unit = {
    val warehouseLocation = new File("spark-warehouse").getAbsolutePath
    val spark=SparkSession
      .builder()
      .appName("demo_3")
      .master("local[*]")
      .config("spark.sql.warehouse.dir",warehouseLocation)
      .enableHiveSupport()//设置支持hive
      .getOrCreate()
    import spark.implicits._
    import spark.sql
    
    sql("show databases").show()//查看hive的数据库
    val apidf=spark.sql(
      """
        |select to_date(date) t,count(1)
        |from data.api
        |where to_date(date)>'2019-02-13'
        |group by to_date(date)
        |order by t
      """.stripMargin).show()
    
}

说下spark.sql.warehouse.dir这个参数,刚开始resources下是有hive的hive-site.xml的

本人是在idea中测试的,如果配置了

val warehouseLocation = new File("spark-warehouse").getAbsolutePath

xxx
.config("spark.sql.warehouse.dir",warehouseLocation)

 会在项目下创建一个spark_warehouse的目录,由于有hive-site.xml,所以该目录为空

把hive-site.xml删掉后,执行以下代码

    sql("show databases").show()
    sql("create database data")

    sql("show databases").show()

执行结果为:

在看项目目录

 spark-warehouse下多了data库,并且多了个元数据的目录

所以就算未配置hive-site.xml,spark也会提供hive的功能,两个目录分别存储元数据和数据。 

如果,有了hive-site.xml,不配置spark.sql.warehouse.dir也没关系。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值