用Apache Spark读取JSON - `corrupt_record`

时间:2016-08-11 11:25:27

标签: json scala apache-spark

我有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读取和操作此记录。

我正试图通过scalaspark-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

4 个答案:

答案 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)

不建议从wholeTextFiles docs

以这种方式读取大文件
  

首选小文件,也允许使用大文件,但可能会导致性能下降。

答案 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"