[英]-Spark Scala Mongodb- MongoTypeConversionException Cannot cast STRING into a StructType(…)
[英]Spark Scala: Cast StructType to String
我讀json為:
val df = spark.read.json(rdd)
我閱讀了來自不同主題的消息,因此無法指定顯式架構。 某些消息包含帶有嵌套json的字段,它們將轉換為StructType。 例如:
{"name": "John", "son": {"name":"Tom"}}
如何將其轉換為String? 我需要將“兒子”字段讀取為字符串:
"{\"name\":\"Tom\"}"
使用cast
方法或sql函數失敗:
df.selectExpr("cast(son as string)")
錯誤:
java.lang.String is not a valid external type for schema of struct<name:string>
您可以使用to_json
輕松返回返回字符串
df.select(to_json(df("son")))
抱歉,我誤解了你的問題。 我以為您有不同的架構,有時字段作為結構返回,有時作為字符串返回,並且您想每次將其轉換為字符串。 我將答案留作參考。
我在本地嘗試了一個小測試用例,顯然如果讓Spark干擾模式,它會將我的“ son”字段視為String。 我不知道您如何構建處理邏輯,但是作為“替代方法”,您可以嘗試手動指定模式並輸入“ son”作為String?
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的架構應用於具有StringType的JSON時,整行都將被忽略(兩個字段均為空值):
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()
它打印:
got=[John,[Tom]]---[null,null]
root
|-- name: string (nullable = true)
|-- son: struct (nullable = true)
| |-- name: string (nullable = true)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.