2016-07-23 115 views
5

我試圖將JSON文件用作小型數據庫。在DataFrame上創建模板表後,我用SQL查詢它並得到一個異常。這裏是我的代碼:在Apache Spark中讀取多行JSON

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 
} 

Exeption:

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| 
|     }| 
+--------------------+ 

UPD2

這很奇怪,但是當我重寫我的JSON,使其oneliner,一切工作正常。

{"id": 1, "name": "Morty", "age": 21} 

所以問題出在newline

UPD3

我在文檔中發現的下一句話:

請注意,是提供一個JSON文件的文件是不是一個典型的JSON文件。每行必須包含一個單獨的,獨立的有效JSON對象。因此,常規的多行JSON文件通常會失敗。

以這種格式保存JSON是不方便的。是否有任何解決方法來擺脫JSON的多線結構或將其轉換爲oneliner?

回答

14

火花> = 2.2

火花2.2引入wholeFilemultiline選項可用於加載JSON(未JSONL)文件:

spark.read 
    .option("multiline", true).option("mode", "PERMISSIVE") 
    .json("/path/to/user.json") 

參見:

  • SPARK-18352 - 解析正常的多行JSON文件les(不只是JSON行)
  • SPARK-20980 - 將選項wholeFile重命名爲multiLine以獲取JSON和CSV。

Spark < 2。2

那麼,使用JSONL格式化數據可能不方便,但我會爭辯說,這不是API的問題,而是格式本身。 JSON的設計根本不是在分佈式系統中並行處理。

它沒有提供模式,也沒有對格式和形狀做出一些非常具體的假設,幾乎不可能正確識別頂級文檔。可以說這是想象在Apache Spark這樣的系統中使用的最糟糕的格式。在分佈式系統中編寫有效的JSON也是非常棘手並且通常不切實際的。

話雖這麼說,如果這些文件是有效的JSON文件(單文檔或文檔數組)你總是可以嘗試wholeTextFiles

spark.read.json(sc.wholeTextFiles("/path/to/user.json").values()) 
2

只是爲了添加到zero323的回答,在星火選項2.2+閱讀多行JSON更名爲multiLine(請參閱Spark文檔here)。

因此,正確的語法是:

spark.read 
    .option("multiLine", true).option("mode", "PERMISSIVE") 
    .json("/path/to/user.json") 

這是發生在https://issues.apache.org/jira/browse/SPARK-20980

+0

「multiline」選項爲我工作。謝謝丹! – Omkar

相關問題