2017-09-27 105 views
1

一個文本文件,裏面我有一個具有JSON數據是這樣的一個文本文件:閱讀JSON使用火花和Scala

​​

所有JSON是新線分離。

我想所有的文本文件中的數據加載到一個臨時的看法:

sqlContext.read.textFiles("/path").createOrReplaceTempView("result") 

val data = sqlContext.sql("select * from result").collect() 

結果:

[{"element" : value,"id" : value,"total" : [] }] 
[{"element" : value,"id" : value, "total" : []}] 

我需要提取的ID和與之相關的總。

火花有辦法解決這個問題嗎?與json數據作爲

​​

+0

您還可以添加從「結果」視圖中顯示數據時得到的結果 –

回答

2

火花SQL每行必須包含一個單獨的,獨立的有效JSON,否則計算失敗。

不過你可以試試這個

spark.read.json(spark.sparkContext.wholeTextFiles("path to json").values) 

spark.read.option("wholeFile", true).option("mode", "PERMISSIVE").json("path to json") 

這應該在JSON轉換成數據幀。

+0

這是什麼意思?你是指json內部的值? – abhi5800

+0

spark.sparkContext.wholeTextFiles(「path to json」)將返回一個RDD .values,並從中選擇rdd的值。答案與選項火花2.2 –

+0

謝謝男人!!它像一個魅力.. :) :)(2.2版幫助..) – abhi5800

0

給定的輸入文件是一個有效的JSON轉換爲一個dataframe,所以你必須將數據轉換成有效火花可讀JSON格式。如果你有值的字符串沒有元素和id字段引號

val rdd = sc.wholeTextFiles("path to the json file") 

val validJsonRdd = rdd.flatMap(_._2.replace(" ", "").replace("\n", "").replace(":value", ":\"value\"").replace("}{", "}\n{").split("\n")) 

上述步驟只會工作。否則,您可以根據自己的需要進行修改。

下一步是使用sqlcontext轉換爲dataframe

val df = sqlContext.read.json(validJsonRdd) 

這將導致以

+-------+-----+-----+ 
|element|id |total| 
+-------+-----+-----+ 
|value |value|[] | 
|value |value|[] | 
+-------+-----+-----+ 

現在你應該能夠選擇id和各自totals和他們一起玩

我希望答案是有幫助的

+0

@這適用於小數據集。但是,如果數據集很大。將所有數據轉換爲有效的JsonRDD將花費大量時間。 – abhi5800

+0

由於我的文本文件已經定義了json對象。我不能直接閱讀它們嗎? – abhi5800

+0

你可以但你必須寫一個JSON解析器,因爲Spark不支持你擁有的JSON類型。 – philantrovert

0

添加到這一點,因爲它花了一些時間去了解它,查詢一些嵌套totals時,您可能需要使用「爆炸」的方法:

Dataset<Row> socials = sparkSession 
      .read() 
      .option("multiLine", true) 
      .option("mode", "PERMISSIVE") 
      .json(<path to file>).cache(); 

socials.select(org.apache.spark.sql.functions.explode(socials.col("total")).as("t")).where("t.<some nested column under total> = 'foo'").toJSON().collectAsList(); 

這是Java火花但希望爆炸的方法會有一些幫助。