Сохранить столбец String как истинное значение Json - Scala - PullRequest
0 голосов
/ 31 октября 2018

У меня есть сценарий использования, где схемой столбца является String, но на самом деле это json (например, "" "{" a ":" b "}" ""). Например:

scala> val list = List("a" -> """ {"a":"b","c":"d"} """, "b" -> """ {"foo" : "bar"} """)
list: List[(String, String)] = List((a," {"a":"b","c":"d"} "), (b," {"foo" : "bar"} "))

scala> val df = list.toDF("colA","colB")
df: org.apache.spark.sql.DataFrame = [colA: string, colB: string]

scala> df.show(2,false)
+----+-------------------+
|colA|colB               |
+----+-------------------+
|a   | {"a":"b","c":"d"} |
|b   | {"foo" : "bar"}   |
+----+-------------------+

Мне нужно написать df как json, но для colB мне нужно вывести истинный json, а не String. Например, если я сделаю это:

scala> df.repartition(1).write.json("/Users/myuser/sparkjson/3")

Я получаю в json-файл colB как String:

{"colA":"a","colB":" {\"a\":\"b\",\"c\":\"d\"} "}
{"colA":"b","colB":" {\"foo\":\"bar\"} "}

Но я хочу вывести true json для colB (вместо строки). Так что-то вроде:

{"colA":"a","colB": {"a":"b","c":"d"} }
{"colA":"b","colB": {"foo":"bar"} }

К сожалению, у меня нет схемы для colB, это может быть любой действительный json. Как мне этого добиться?

Ответы [ 2 ]

0 голосов
/ 31 октября 2018

Не совсем уверен в этом решении, но можно попробовать добавить опцию, подобную следующей -

scala> df.repartition(1).write.option("escapeQuotes","false").json("/Users/myuser/sparkjson/3")
0 голосов
/ 31 октября 2018

Вам нужно создать DataFrame с правильной схемой, в этом случае colB на самом деле Map[String, String], простой способ сделать это - создать case class, и spark вычислит вашу схему автоматически. Вот код:

import org.json4s._
import org.json4s.jackson.JsonMethods._
implicit val formats = DefaultFormats

case class Data(colA:String, colB:Map[String, String])

val list:List[Data] =
List("a" -> """ {"a":"b","c":"d"} """, "b" -> """ {"foo" : "bar"} """) .map {
  case (colA, colB) => 
      Data(
       colA,
       parse(colB).extract[Map[String, String]]
      )
}

val df = spark.createDataset( list )
df.write.json("/tmp/a.json")

Результат как ниже:

$ cat /tmp/a.json/*                                                                            
{"colA":"a","colB":{"a":"b","c":"d"}}
{"colA":"b","colB":{"foo":"bar"}}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...