JSONファイルを小さなDBとして使用しようとしていました。 DataFrameでテンプレートテーブルを作成した後、SQLでクエリを実行すると例外が発生しました。ここに私のコードがあります:
_val df = sqlCtx.read.json("/path/to/user.json")
df.registerTempTable("user_tt")
val info = sqlCtx.sql("SELECT name FROM user_tt")
info.show()
_
df.printSchema()
結果:
_root
|-- _corrupt_record: string (nullable = true)
_
私のJSONファイル:
_{
"id": 1,
"name": "Morty",
"age": 21
}
_
例外:
_Exception in thread "main" org.Apache.spark.sql.AnalysisException: cannot resolve 'name' given input columns: [_corrupt_record];
_
どうすれば修正できますか?
[〜#〜] upd [〜#〜]
__corrupt_record
_は
_+--------------------+
| _corrupt_record|
+--------------------+
| {|
| "id": 1,|
| "name": "Morty",|
| "age": 21|
| }|
+--------------------+
_
PD2
奇妙ですが、JSONを書き直してonelinerにすると、すべて正常に動作します。
_{"id": 1, "name": "Morty", "age": 21}
_
したがって、問題はnewline
にあります。
PD
私はドキュメントで次の文を見つけました:
Jsonファイルとして提供されるファイルは、一般的なJSONファイルではないことに注意してください。各行には、独立した独立した有効なJSONオブジェクトが含まれている必要があります。結果として、通常の複数行JSONファイルはほとんどの場合失敗します。
JSONをこのような形式に保つのは便利ではありません。 JSONの複数行構造を取り除く、またはonelinerで変換する回避策はありますか?
Spark> = 2.2
Spark 2.2が導入されました JSON(JSONLではない)ファイルのロードに使用できるwholeFile
multiLine
オプション:
spark.read
.option("multiLine", true).option("mode", "PERMISSIVE")
.json("/path/to/user.json")
見る:
wholeFile
からmultiLine
に変更します。スパーク<2.2
まあ、JSONL形式のデータを使用するのは不便かもしれませんが、それはAPIの問題ではなく、形式そのものです。 JSONは、分散システムで並列処理されるように設計されていないだけです。
それはスキーマを提供せず、その書式設定と形状についていくつかの非常に具体的な仮定を行うことなく、トップレベルのドキュメントを正しく識別することはほとんど不可能です。おそらくこれは、Apache Sparkのようなシステムで使用するために想像できる最悪の形式です。また、分散システムで有効なJSONを記述することは非常に難しく、通常は実用的ではありません。
つまり、個々のファイルが有効なJSONドキュメント(単一のドキュメントまたはドキュメントの配列)である場合は、常にwholeTextFiles
を試すことができます。
spark.read.json(sc.wholeTextFiles("/path/to/user.json").values())
Zero323の答えに追加するために、Spark 2.2+の複数行JSONを読み取るオプションがmultiLine
に名前が変更されました(Spark =ドキュメント ここ )。
したがって、正しい構文は次のとおりです。
spark.read
.option("multiLine", true).option("mode", "PERMISSIVE")
.json("/path/to/user.json")
これは https://issues.Apache.org/jira/browse/SPARK-2098 で発生しました。