背景
在使用sparksql创建DataFrame的时候,读取的数据包含_corrupt_record,在操作过程中产生错乱的问题,代码如下
当前spark版本:2.1.1
当前使用scala兼容版本:2.11
<!-- 版本 -->
<properties>
<encoding>UTF-8</encoding>
<scala.version>2.11.8</scala.version>
<scala.compat.version>2.11</scala.compat.version>
<spark.version>2.1.1</spark.version>
</properties>
<!-- 依赖 -->
<dependency>
<groupId>org.apache.spark</groupId>
<artifactId>spark-sql_${scala.compat.version}</artifactId>
<version>${spark.version}</version>
</dependency>
<dependency>
<groupId>org.apache.spark</groupId>
<artifactId>spark-core_${scala.compat.version}</artifactId>
<version>${spark.version}</version>
<exclusions>
<exclusion>
<artifactId>slf4j-log4j12</artifactId>
<groupId>org.slf4j</groupId>
</exclusion>
</exclusions>
</dependency>
package com.example.scala.rdd
import org.apache.spark.sql.SparkSession
object DataFrameDemo {
def testSql(session: SparkSession) = {
//可以使用绝对路径,也可以使用相对路径
val json = session.read.json("scala-demo\\src\\main\\scala\\com\\example\\scala\\rdd\\emperor.json")
json.show()
json.printSchema()
json.createGlobalTempView("emperor")
val sql1 = session.sql("select name,age from global_temp.emperor")
// 直接进行sql运算
val sql2 = session.sql("select name,age+1 as age from global_temp.emperor")
println("指定列字段查询结构: ")
sql1.show()
println("字段运算查询结果: ")
sql2.show()
println("分组查询结果")
val sql3 = session.sql("select age ,count(1) from global_temp.emperor group by age")
sql3.show()
}
def main(args: Array[String]): Unit = {
val b = SparkSession.builder().master("local")
val session: SparkSession = b.getOrCreate()
session.sparkContext.getConf.setMaster("local")
testSql(session)
session.stop()
}
}
原数据
[
{"name": "朱元璋", "age": 38 },
{"name": "朱允文", "age": 25 },
{"name": "朱棣", "age": 38 },
{"name": "朱高炽(chi)", "age": 25 }
]
结果输出
解决方式
解决方式一
1.DataFrame创建的时候,原数据是以行为读取单位的
2.session.read.json("path.json") 源文件每一行为一个jsonn结构(可以不用逗号隔开)
原数据更改如下
{"name": "朱元璋", "age": 38 }
{"name": "朱允文", "age": 25 }
{"name": "朱棣", "age": 38 }
{"name": "朱高炽(chi)", "age": 25 }
解决方式二
升级spark版本,该问题在版本2.2.0开始引入配置参数
版本:
<spark.version>2.2.0</spark.version>
配置参数:session.read.option("multiLine", true).json("path.json")
val json = session.read.option("multiLine", true).json("scala-demo\\src\\main\\scala\\com\\example\\scala\\rdd\\emperor.json")
重新执行结果
+---+--------+
|age| name|
+---+--------+
| 38| 朱元璋|
| 25| 朱允文|
| 38| 朱棣|
| 25|朱高炽(chi)|
+---+--------+
root
|-- age: long (nullable = true)
|-- name: string (nullable = true)
指定列字段查询结构:
+--------+---+
| name|age|
+--------+---+
| 朱元璋| 38|
| 朱允文| 25|
| 朱棣| 38|
|朱高炽(chi)| 25|
+--------+---+
字段运算查询结果:
+--------+---+
| name|age|
+--------+---+
| 朱元璋| 39|
| 朱允文| 26|
| 朱棣| 39|
|朱高炽(chi)| 26|
+--------+---+
分组查询结果
+---+--------+
|age|count(1)|
+---+--------+
| 25| 2|
| 38| 2|
+---+--------+