spark(21)DataSet概述、构建DataSet
DataSet概述
DataSet是什么
DataSet是分布式的数据集合,Dataset提供了强类型支持,也是在RDD的每行数据加了类型约束。
强类型:所属类型必须在编译时确定。
DataSet是在Spark1.6中添加的新的接口。它集中了RDD的优点(强类型和可以用强大lambda函数)以及使用了Spark SQL优化的执行引擎。
RDD、DataFrame、DataSet的区别
假设RDD中的两行数据长这样
那么DataFrame中的数据长这样
Dataset中的数据长这样
或者长这样(每行数据是个Object)
DataSet包含了DataFrame的功能,Spark2.0中两者统一,DataFrame表示为DataSet[Row],即DataSet的子集。
- DataSet可以在编译时检查类型
- 并且是面向对象的编程接口
DataSet与DataFrame源码分析
我们来查看以下DataSet与DataFrame的源码,进入IDEA,添加以下pom依赖:
<dependency>
<groupId>org.apache.spark</groupId>
<artifactId>spark-sql_2.11</artifactId>
<version>2.3.3</version>
</dependency>
按住ctrl+N,搜索DataFrame类,发现搜索不到,搜索DataSet类,成功。download source。
发现DataSet的源码包含以下代码:
def toDF(): DataFrame = new Dataset[Row](sparkSession, queryExecution, RowEncoder(schema))
toDF()方法是一个返回值类型为DataFrame,点击查看该DataFrame的源码,如下,发现DataFrame类型就是一个Dataset[Row]类型。这就是DataFrame表示为DataSet[Row],即DataSet的子集的原因。
package object sql {
@DeveloperApi
@InterfaceStability.Unstable
type Strategy = SparkStrategy
type DataFrame = Dataset[Row]
}
DataFrame与DataSet互相转换
把一个DataFrame转换成DataSet
val dataSet=dataFrame.as[强类型]
把一个DataSet转换成DataFrame
val dataFrame=dataSet.toDF
补充说明: 可以从dataFrame和dataSet获取得到rdd
val rdd1=dataFrame.rdd
val rdd2=dataSet.rdd
转换示例:
scala> val df=spark.read.text("/person.txt")
df: org.apache.spark.sql.DataFrame = [value: string]
scala> df.show
+-------------+
| value|
+-------------+
|1 zhangsan 20|
| 2 lisi 32|
| 3 laowang 46|
+-------------+
scala> val ds=df.as[String]
ds: org.apache.spark.sql.Dataset[String] = [value: string]
scala> ds.show
+-------------+
| value|
+-------------+
|1 zhangsan 20|
| 2 lisi 32|
| 3 laowang 46|
+-------------+
构建DataSet
1、通过sparkSession调用createDataset方法
scala> val ds=spark.createDataset(1 to 10)
ds: org.apache.spark.sql.Dataset[Int] = [value: int]
scala> ds.show
+-----+
|value|
+-----+
| 1|
| 2|
| 3|
| 4|
| 5|
| 6|
| 7|
| 8|
| 9|
| 10|
+-----+
scala> val ds=spark.createDataset(sc.textFile("/person.txt"))
ds: org.apache.spark.sql.Dataset[String] = [value: string]
scala> ds.show
+-------------+
| value|
+-------------+
|1 zhangsan 20|
| 2 lisi 32|
| 3 laowang 46|
+-------------+
2、使用scala集合和rdd调用toDS方法
scala> val ds=sc.textFile("/person.txt").toDS
ds: org.apache.spark.sql.Dataset[String] = [value: string]
scala> ds.show
+-------------+
| value|
+-------------+
|1 zhangsan 20|
| 2 lisi 32|
| 3 laowang 46|
+-------------+
scala> List(1,2,4).toDS
res20: org.apache.spark.sql.Dataset[Int] = [value: int]
scala> List(1,2,4).toDS.show
+-----+
|value|
+-----+
| 1|
| 2|
| 4|
+-----+
3、把一个DataFrame转换成DataSet
scala> case class Person(name:String,age:Long)
defined class Person
scala> val peopleDS=spark.read.json("/people.json").as[Person]
peopleDS: org.apache.spark.sql.Dataset[Person] = [age: bigint, name: string]
scala> peopleDS
res13: org.apache.spark.sql.Dataset[Person] = [age: bigint, name: string]
scala> peopleDS.show
+----+-------+
| age| name|
+----+-------+
|null|Michael|
| 30| Andy|
| 19| Justin|
+----+-------+
4、通过一个DataSet转换生成一个新的DataSet
scala> List(1,2,3,4,5).toDS.map(x=>x*10)
res22: org.apache.spark.sql.Dataset[Int] = [value: int]
scala> List(1,2,3,4,5).toDS.map(x=>x*10).show
+-----+
|value|
+-----+
| 10|
| 20|
| 30|
| 40|
| 50|
+-----+