Извините, я неправильно понял ваш вопрос.Я думал, что у вас была другая схема, и иногда поле возвращалось как структура, а иногда как строка, и вы хотели каждый раз преобразовывать ее в строку.Я оставляю ответ только для информационных целей.
Я пробовал небольшой тестовый пример локально, и, по-видимому, если я позволю Spark вмешиваться в схему, он считает мое поле "сын" строкой.Я не знаю, как вы строите логику обработки, но в качестве «обходного пути» вы можете попытаться указать схему вручную и ввести «son» в качестве строки?
val testDataset =
"""
| {"name": "John", "son": {"name":"Tom"}}
| {"name": "John", "son": "Tom"}
""".stripMargin
val testJsonFile = new File("./test_json.json")
FileUtils.writeStringToFile(testJsonFile, testDataset)
val schema = StructType(
Seq(StructField("name", DataTypes.StringType, true), StructField("son", DataTypes.StringType, true))
)
val sparkSession = SparkSession.builder()
.appName("Test inconsistent field type").master("local[*]").getOrCreate()
val structuredJsonData = sparkSession.read.schema(schema).json(testJsonFile.getAbsolutePath)
import sparkSession.implicits._
val collectedDataset = structuredJsonData.map(row => row.getAs[String]("son")).collect()
println(s"got=${collectedDataset.mkString("---")}")
structuredJsonData.printSchema()
Он печатает:
got={"name":"Tom"}---Tom
root
|-- name: string (nullable = true)
|-- son: string (nullable = true)
Вы все еще можете попытаться определить пользовательскую функцию отображения.Однако я не уверен, что это сработает, потому что когда я пытаюсь применить схему со StructType к JSON с StringType, вся строка игнорируется (нулевые значения в обоих полях):
val testDataset =
"""
| {"name": "John", "son": {"name":"Tom"}}
| {"name": "John", "son": "Tom2"}
""".stripMargin
val testJsonFile = new File("./test_json.json")
FileUtils.writeStringToFile(testJsonFile, testDataset)
val schema = StructType(
Seq(StructField("name", DataTypes.StringType, true), StructField("son", StructType(Seq(StructField("name", DataTypes.StringType, true))))
)
)
val sparkSession = SparkSession.builder()
.appName("Test inconsistent field type").master("local[*]").getOrCreate()
val structuredJsonData = sparkSession.read.schema(schema).json(testJsonFile.getAbsolutePath)
println(s"got=${structuredJsonData.collect().mkString("---")}")
structuredJsonData.printSchema()
Itотпечатки:
got=[John,[Tom]]---[null,null]
root
|-- name: string (nullable = true)
|-- son: struct (nullable = true)
| |-- name: string (nullable = true)