web-dev-qa-db-ja.com

ApacheでJSONを読むSpark-`corrupt_record`

次のような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でこのレコードを読み取り、操作することができます。

spark-Shellを介してscalaにあるこのファイルを読み取ろうとしています。

これから チュートリアル から、sqlContext.read.json経由でjsonを読み取ることができることがわかります。

val vfile = sqlContext.read.json("path/to/file/nodes.json")

ただし、これはcorrupt_recordエラーになります。

vfile: org.Apache.spark.sql.DataFrame = [_corrupt_record: string]

誰もがこのエラーにいくつかの光を当てることができますか?他のアプリケーションでこのファイルを読み取って使用できますが、ファイルが破損しておらず、jsonであると確信しています。

13
LearningSlowly

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}

チュートリアル で説明されているように、あなたは以下を参照しています:

各行がJSONオブジェクトであるJSONファイルをロードすることから始めましょう

推論は非常に簡単です。 Sparkは、多くのJSONエンティティを持つファイルを渡すことを期待しているため、その処理を(おおまかに言ってエンティティごとに)分散できます。そのため、トップレベルのエンティティを解析することを期待しているが、そのような列の名前がないためにレコードにマッピングすることは不可能な配列を取得します。基本的に(正確ではありませんが)Sparkは、配列を1列の1行として認識し、その列の名前を見つけることができません。

それにもっと光を置くために、ここに引用形式があります 公式ドキュメント

Jsonファイルとして提供されるファイルは、一般的なJSONファイルではないことに注意してください。各行には、独立した独立した有効なJSONオブジェクトが含まれている必要があります。結果として、通常の複数行JSONファイルはほとんどの場合失敗します。

この形式は、多くの場合 [〜#〜] jsonl [〜#〜] と呼ばれます。基本的に、CSVに代わるものです。

18
dk14

複数行のJSONをDataFrameとして読み取るには:

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

val df = spark.read.json(spark.sparkContext.wholeTextFiles("file.json").values)

wholeTextFiles docs から、この方法で大きなファイルを読み取ることはお勧めしません

小さいファイルが優先され、大きいファイルも使用できますが、パフォーマンスが低下する可能性があります。

11
Datageek

Sparkは「JSON行形式」が典型的なJSON形式ではないことを期待しているため、sparkを指定して典型的なJSONを読み取るように指示できます。

val df = spark.read.option("multiline", "true").json("<file>")
7
SandeepGodara

私は同じ問題に遭遇します。同じ構成で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"
0
Robert Gabriel