Фон
Я сглаживаю вложенную схему для данного 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\"] }"
}
}