преобразовать столбец массива значений в строковый столбец (содержащий сериализованный JSON) - PullRequest
0 голосов
/ 06 мая 2018

Фон

Я сглаживаю вложенную схему для данного Spark DataSet, сначала создав сопоставление конечных узлов / типов из StructType из dataset.schema(), затем используя col.alias(...) и select(reAliasedCols) для получения уплощенного набора данных. Например:

Выпуск

Вместо того, чтобы поворачивать / взрывать поля типа массива, я хотел бы сериализовать их в строку JSON.

Этот подход, кажется, почти работает с использованием функции to_json для сериализации массива, как в следующем надуманном примере: dataset.select(to_json(dataset.col("item.messages")).alias("item_messages")).

К сожалению, это не работает для столбцов, содержащих массивы примитивов (массивы структур / объектов правильно сериализуются) следующим образом:

org.apache.spark.sql.AnalysisException: cannot resolve 'structstojson(`item`.`messages`)'
   due to data type mismatch: Input type array<string>
   must be a struct, array of structs or a map or array of map.;;

Похоже, to_json не поддерживает сериализацию массивов примитивов, поддерживая только " StructType, ArrayType для StructTypes, MapType или ArrayType для MapTypes " (несмотря на SPARK-21513: SQL to_json должен поддерживать все типы столбцов

Примеры наборов данных / схем:

Имеется набор данных из строковых записей, таких как:

{
  "item": {
    "messages": [
      "test",
      "test2",
      "test3"
    ]
  }
}

Который при загрузке с read().json(dataSetOfJsonStrings) создает схему вроде:

root
 |-- item: struct (nullable = true)
 |    |-- messages: array (nullable = true)
 |    |    |-- element: string (containsNull = true)

Как преобразовать столбцы ArrayType в сериализованный json? Например, эта схема:

root
 |-- item: struct (nullable = true)
 |    |-- messages: string (nullable = true)

Что может быть записано в формате JSON, например:

{
  "item": {
    "messages": "[\"test\",\"test2\",\"test3\"]"
  }
}

Примечание: пример вывода не сплющен, просто иллюстрирует использование to_json ().

Вопрос:

Можно ли сериализовать массив примитивов при таком преобразовании?

Я хотел бы сохранить структуру любого столбца типа массива, например, не оборачивая столбцы типа массива в структуру, чтобы разрешить сериализацию через to_json:

to_json(struct(dataset.col("item.messages"))).alias("item_messages")

Который производит что-то вроде этого:

{
  "item": {
    "messages": "{ \"messages\": [\"test\",\"test2\",\"test3\"] }"
  }
}
...