Массив Spark JSON

#json #apache-spark

#json #apache-spark

Вопрос:

У меня есть Spark DataFrame со следующими столбцами

 uuid|some_data
"A" |"ABC"
"B" |"DEF"
  

Мне нужно преобразовать это во вложенный JSON следующего формата,

 {"data":[{"attributes":[{"uuid":"A","some_data":"ABC"}]}]}
{"data":[{"attributes":[{"uuid":"B","some_data":"DEF"}]}]}
  

Я попробовал приведенный ниже код для достижения этой цели,

 val jsonDF= dataFrame.select(
  to_json(struct(dataFrame.columns.map(column):_*)).alias("attributes")
)

val jsonDF2= jsonDF.select(
  to_json(struct(jsonDF(column):_*)).alias("data")
)

val jsonDF3= jsonDF2(
  to_json(struct(jsonDF2.columns.map(column):_*)).alias("value")
).selectExpr("CAST(value as STRING)")
  

В итоге был получен следующий формат,

 {"data": {"attributes": {"uuid":"A","some_data":"ABC}}}
{"data": {"attributes": {"uuid":"B","some_data":"DEF}}}
  

Пожалуйста, дайте мне знать, какие изменения мне нужно внести, чтобы привести его к требуемому формату.

Ответ №1:

Для каждого документа JSON требуется свой собственный struct . Дополнительно вам понадобится array для обертывания data и еще один для обертывания attributes :

 import org.apache.spark.sql.functions.{array, struct}

val jsonData = struct(     // Outermost JSON document
  array(                   // Data field as an array
    struct(                // Intermediate JSON document with attributes field
      array(               // Innermost array
        struct(            // Innermost JSON document 
          $"uuid",         // Payload, you can use df.columns.map(col):_* instead
          $"some_data"
        )  
      ) as "attributes"    // Alias for innermost array field
    )
) as "data")               // Alias for array field
  

Комбинированный:

 Seq(("A", "ABC"))
  .toDF("uuid", "some_data")
  .select(to_json(jsonData) as "data")
  .show(false)
  
  ---------------------------------------------------------- 
|data                                                      |
 ---------------------------------------------------------- 
|{"data":[{"attributes":[{"uuid":"A","some_data":"ABC"}]}]}|
 ----------------------------------------------------------