用Apache Spark读取JSON - `corrupt_record`

Lea*_*wly 15 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}]
Run Code Online (Sandbox Code Playgroud)

我能够使用Python读取和操作此记录.

我试图scala通过这个读取此文件spark-shell.

从这个教程中,我可以看到,它可以读取json通过sqlContext.read.json

val vfile = sqlContext.read.json("path/to/file/nodes.json")
Run Code Online (Sandbox Code Playgroud)

但是,这会导致corrupt_record错误:

vfile: org.apache.spark.sql.DataFrame = [_corrupt_record: string]
Run Code Online (Sandbox Code Playgroud)

任何人都可以对这个错误有所了解吗?我可以阅读和使用该文件与其他应用程序,我相信它没有腐败和声音json.

dk1*_*k14 20

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}
Run Code Online (Sandbox Code Playgroud)

正如教程中所描述的那样,您指的是:

让我们首先加载一个JSON文件,其中每一行都是一个JSON对象

推理很简单.Spark希望您传递一个包含大量JSON实体的文件,因此它可以分发它们的处理(按实体,粗略地说).所以这就是为什么它希望在顶级解析一个实体但得到一个数组,这是不可能映射到一个记录,因为这个列没有名称.基本上(但不是很精确)Spark将您的数组视为一行,只有一列,并且无法找到该列的名称.

为了更加清楚,这里是官方文档的引用

请注意,作为json文件提供的文件不是典型的JSON文件.每行必须包含一个单独的,自包含的有效JSON对象.因此,常规的多行JSON文件通常会失败.

这种格式通常称为JSONL.基本上它是CSV的替代品.


Dat*_*eek 11

要将多行JSON读取为DataFrame:

val spark = SparkSession.builder().getOrCreate()

val df = spark.read.json(spark.sparkContext.wholeTextFiles("file.json").values)
Run Code Online (Sandbox Code Playgroud)

从整个文本文件中不建议以这种方式读取大文件

小文件是首选,大文件也是允许的,但可能会导致性能不佳.


San*_*ara 9

由于Spark期望“ JSON行格式”不是典型的JSON格式,因此我们可以通过指定以下内容来告知spark读取典型的JSON:

val df = spark.read.option("multiline", "true").json("<file>")
Run Code Online (Sandbox Code Playgroud)