簡體   English   中英

Spark Scala:將StructType轉換為String

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM