Чтение CSV-файлов содержит структурный тип в Spark с использованием Java - PullRequest
0 голосов
/ 10 октября 2019

Я пытаюсь написать тестовый пример для программы. Для этого я читаю CSV-файл, содержащий данные в следующем формате.
account_number,struct_data 123456789,{"key1":"value","key2":"value2","keyn":"valuen"} 987678909,{"key1":"value0","key2":"value20","keyn":"valuen0"}
несколько сотен таких строк.

Мне нужно прочитать второй столбец как структуру. Но я получаю сообщение об ошибке struct type expected, string type found

Я пробовал приводить как StructType, а затем получаю сообщение об ошибке: «StringType не может быть преобразован в StructType».

Должен ли я изменить способ отображения CSV? Что еще я могу сделать?

Ответы [ 2 ]

0 голосов
/ 10 октября 2019

Если все записи json имеют одну и ту же схему, вы можете определить ее и использовать функцию sparks from_json() для выполнения вашей задачи.

import org.apache.spark.sql.types.StructType

val df = Seq(
    (123456789, "{\"key1\":\"value\",\"key2\":\"value2\",\"keyn\":\"valuen\"}"),
    (987678909, "{\"key1\":\"value0\",\"key2\":\"value20\",\"keyn\":\"valuen0\"}")
    ).toDF("account_number", "struct_data")

val schema = new StructType()
  .add($"key1".string)
  .add($"key2".string)
  .add($"keyn".string)

 val df2 = df.withColumn("st", from_json($"struct_data", schema))

 df2.printSchema
 df2.show(false)

Этот фрагмент кода приводит к следующемувывод:

root
 |-- account_number: integer (nullable = false)
 |-- struct_data: string (nullable = true)
 |-- st: struct (nullable = true)
 |    |-- key1: string (nullable = true)
 |    |-- key2: string (nullable = true)
 |    |-- keyn: string (nullable = true)

+--------------+---------------------------------------------------+------------------------+
|account_number|struct_data                                        |st                      |
+--------------+---------------------------------------------------+------------------------+
|123456789     |{"key1":"value","key2":"value2","keyn":"valuen"}   |[value,value2,valuen]   |
|987678909     |{"key1":"value0","key2":"value20","keyn":"valuen0"}|[value0,value20,valuen0]|
+--------------+---------------------------------------------------+------------------------+
0 голосов
/ 10 октября 2019

Я дал свое решение в Scala Spark, оно может дать некоторое представление о вашем запросе

scala> val sdf = """{"df":[{"actNum": "1234123", "strType": [{"key1": "value1", "key2": "value2"}]}]}"""
sdf: String = {"df":[{"actNum": "1234123", "strType": [{"key1": "value1", "key2": "value2"}]}]}

scala> val erdf = spark.read.json(Seq(sdf).toDS).toDF().withColumn("arr", explode($"df")).select("arr.*")
erdf: org.apache.spark.sql.DataFrame = [actNum: string, strType: array<struct<key1:string,key2:string>>]

scala> erdf.show()
+-------+-----------------+
| actNum|          strType|
+-------+-----------------+
|1234123|[[value1,value2]]|
+-------+-----------------+


scala> erdf.printSchema
root
 |-- actNum: string (nullable = true)
 |-- strType: array (nullable = true)
 |    |-- element: struct (containsNull = true)
 |    |    |-- key1: string (nullable = true)
 |    |    |-- key2: string (nullable = true)

...