我有json
个文件nodes
,如下所示:
[{"toid":"osgb4000000031043205","point":[508180.748,195333.973],"index":1}
,{"toid":"osgb4000000031043206","point":[508163.122,195316.627],"index":2}
,{"toid":"osgb4000000031043207","point":[508172.075,195325.719],"index":3}
,{"toid":"osgb4000000031043208","point":[508513,196023],"index":4}]
我能够使用Python读取和操作此记录。
我正试图通过scala
在spark-shell
中阅读此文件。
通过此tutorial,我可以看到可以通过json
sqlContext.read.json
val vfile = sqlContext.read.json("path/to/file/nodes.json")
但是,这会导致corrupt_record
错误:
vfile: org.apache.spark.sql.DataFrame = [_corrupt_record: string]
有人可以解释这个错误吗?我可以阅读并使用该文件与其他应用程序,我相信它没有腐败和声音json
。
答案 0 :(得分:17)
Spark无法将JSON数组读取到顶级记录,因此您必须传递:
{"toid":"osgb4000000031043205","point":[508180.748,195333.973],"index":1}
{"toid":"osgb4000000031043206","point":[508163.122,195316.627],"index":2}
{"toid":"osgb4000000031043207","point":[508172.075,195325.719],"index":3}
{"toid":"osgb4000000031043208","point":[508513,196023],"index":4}
正如the tutorial中所述,您指的是:
让我们首先加载一个JSON文件,其中每一行是一个JSON对象
推理很简单。 Spark希望您传递一个包含大量JSON实体的文件,因此它可以分发它们的处理(按实体,粗略地说)。所以这就是为什么它希望在顶层解析一个实体但得到一个数组,这是不可能映射到记录的,因为这个列没有名称。基本上(但不是很精确)Spark会将您的数组视为一行,只有一列,但无法找到该列的名称。
为了更加清晰,请点击此处the official doc
请注意,作为json文件提供的文件不是典型的 JSON文件。每行必须包含一个单独的,独立的有效内容 JSON对象。因此,常规的多行JSON文件将会 最常见的是失败。
此格式通常称为JSONL。基本上它是CSV的替代品。
答案 1 :(得分:11)
将多行JSON读取为DataFrame:
val spark = SparkSession.builder().getOrCreate()
val df = spark.read.json(spark.sparkContext.wholeTextFiles("file.json").values)
以这种方式读取大文件
首选小文件,也允许使用大文件,但可能会导致性能下降。
答案 2 :(得分:5)
由于Spark期望“ JSON行格式”不是典型的JSON格式,因此我们可以通过指定以下内容来告知Spark读取典型的JSON:
val df = spark.read.option("multiline", "true").json("<file>")
答案 3 :(得分:0)
我遇到了同样的问题。我在相同的配置上使用了sparkContext和sparkSql:
val conf = new SparkConf()
.setMaster("local[1]")
.setAppName("Simple Application")
val sc = new SparkContext(conf)
val spark = SparkSession
.builder()
.config(conf)
.getOrCreate()
然后,使用spark上下文我读取了整个json(JSON - 文件路径)文件:
val jsonRDD = sc.wholeTextFiles(JSON).map(x => x._2)
您可以为将来的选择创建架构,过滤器......
val schema = StructType( List(
StructField("toid", StringType, nullable = true),
StructField("point", ArrayType(DoubleType), nullable = true),
StructField("index", DoubleType, nullable = true)
))
使用spark sql创建一个DataFrame:
var df: DataFrame = spark.read.schema(schema).json(jsonRDD).toDF()
测试时使用show和printSchema:
df.show()
df.printSchema()
sbt构建文件:
name := "spark-single"
version := "1.0"
scalaVersion := "2.11.7"
libraryDependencies += "org.apache.spark" %% "spark-core" % "2.0.2"
libraryDependencies +="org.apache.spark" %% "spark-sql" % "2.0.2"