Spark JSON чтения полей, которые являются дополнительными в JSON в классы дел - PullRequest
2 голосов
/ 04 февраля 2020

Рассмотрим следующую схему класса дела:

case class Y (a: String, b: String)
case class X (dummy: String, b: Y)

Поле b является необязательным, некоторые из моих наборов данных не имеют поля b. Когда я пытаюсь прочитать строку JSON, которая не содержит, я получаю исключение пропущенного поля.

spark.read.json(Seq("{'dummy': '1', 'b': {'a': '1'}}").toDS).as[X]
org.apache.spark.sql.AnalysisException: No such struct field b in a;
  at org.apache.spark.sql.catalyst.expressions.ExtractValue$.findField(complexTypeExtractors.scala:85)
  at org.apache.spark.sql.catalyst.expressions.ExtractValue$.apply(complexTypeExtractors.scala:53)
  at org.apache.spark.sql.catalyst.analysis.Analyzer$$anonfun$resolveExpression$1.applyOrElse(Analyzer.scala:1074)
  at org.apache.spark.sql.catalyst.analysis.Analyzer$$anonfun$resolveExpression$1.applyOrElse(Analyzer.scala:1065)
  at org.apache.spark.sql.catalyst.trees.TreeNode$$anonfun$transformUp$2.apply(TreeNode.scala:282)
  at org.apache.spark.sql.catalyst.trees.TreeNode$$anonfun$transformUp$2.apply(TreeNode.scala:282)
  at org.apache.spark.sql.catalyst.trees.CurrentOrigin$.withOrigin(TreeNode.scala:70)

Как автоматически десериализовать поля, которых нет в JSON, чтобы они были как ноль?

1 Ответ

3 голосов
/ 04 февраля 2020

Определите поле b как тип Option и используйте кодировщики для создания схемы типа структуры.

  • Передайте определенную схему, используя параметр .schema с case class X для создания набора данных!

Example:

case class Y (a: String, b: Option[String] = None)
case class X (dummy: String, b: Y)

import org.apache.spark.sql.Encoders

val schema = Encoders.product[X].schema

spark.read.schema(schema).json(Seq("{'dummy': '1', 'b': {'a': '1'}}").toDS).as[X].show()

//+-----+----+
//|dummy|   b|
//+-----+----+
//|    1|[1,]|
//+-----+----+

Select b column from struct type:

spark.read.schema(schema).json(Seq("{'dummy': '1', 'b': {'a': '1'}}").toDS).as[X].
select("b.b").show()

//+----+
//|   b|
//+----+
//|null|
//+----+

PrintSchema:

spark.read.schema(schema).json(Seq("{'dummy': '1', 'b': {'a': '1'}}").toDS).as[X].printSchema

//root
 //|-- dummy: string (nullable = true)
 //|-- b: struct (nullable = true)
 //|    |-- a: string (nullable = true)
 //|    |-- b: string (nullable = true)
...