Spark可以读取JSON,将其转换为DataFrame ( DataFrame[Row] )
Spark SQL可以自动推断JSON的schema,但是如果显式的提供模式可以避免额外的扫描
需要注意是:如果是读取JSON文件,提供的json文件不是典型的JSON文件,而是每行属于合法的JSON,然后用分隔符分割,具体规则:http://jsonlines.org/
官网Demo地址:http://spark.apache.org/docs/latest/sql-data-sources-json.html
读取JSON文件
// 以下是测试文件的json
//{"id": 1, "name": "mwf", "age": 23}
//{"id": 2, "name": "zqr", "age": 23}
val structType = new StructType()
.add("id", IntegerType)
.add("name", StringType)
.add("age", IntegerType)
//读json文件,读取的时候也可以不指定schema,spark可以自动推断类型
val jsonDF = spark
.read
.schema(structType)
.json("D:\\learning_spark\\spark_demo\\src\\main\\resources\\read_json.jsonl")
jsonDF.printSchema()
jsonDF.show()
读取JSON String
val seq = Seq("{\"id\": 1, \"name\": \"mwf\", \"age\": 23}",
"{\"id\": 2, \"name\": \"zqr\", \"age\": 23}")
val jsonStringRdd = spark
.sparkContext
.parallelize(seq)
import spark.implicits._
// 也可以直接创建DS spark.createDataset(seq)
val jsonDS= jsonStringRdd.toDS()
//也可以直接传jsonStringRdd, 不过spark建议我们传入DataSet
val jsonDF2 = spark
.read
.json(jsonDS)
jsonDF2.show()
读取JSON的时候,存在的坑
当不指定schema时,可以读到正确的JSON;但是当指定schema后,读取到的JSON值都为null
{"id": "1", "name": "mwf", "age": 23}
{"id": "2", "name": "zqr", "age": 23}
以上JSON,我们如果指定如下schema:
val structType = new StructType()
.add("id", IntegerType)
.add("name", StringType)
.add("age", IntegerType)
读取出来就会 每行都变为null
将注意力放到"id":"1"那里,1是加了引号的,意味着他是一个字符串,而不是int类型的
spark无法直接从String转换为Integer,会将整行记录置为null
要解决如上问题,我们可以将id变为int值;或者直接将schema的类型都指定为String,在读取进来以后再处理为想要的类型
以下两个网站解决了我的疑问,大家也可以直接点过去看
https://codeday.me/bug/20190406/896703.html
https://blog.antlypls.com/blog/2016/01/30/processing-json-data-with-sparksql
居安思危,跳出安逸!