Apache Spark 2.0: java.lang.UnsupportedOperationException: кодировщик для java.time.LocalDate не найден

Я использую Apache Spark 2.0 и создаю case class схему упоминания для DetaSet. Когда я пытаюсь определить пользовательский кодировщик в соответствии с Как сохранить пользовательские объекты в наборе данных?, для java.time.LocalDate возникло следующее исключение:

java.lang.UnsupportedOperationException: No Encoder found for java.time.LocalDate
- field (class: "java.time.LocalDate", name: "callDate")
- root class: "FireService"
at org.apache.spark.sql.catalyst.ScalaReflection$.org$apache$spark$sql$catalyst$ScalaReflection$$serializerFor(ScalaReflection.scala:598)
at org.apache.spark.sql.catalyst.ScalaReflection$$anonfun$9.apply(ScalaReflection.scala:592)
at org.apache.spark.sql.catalyst.ScalaReflection$$anonfun$9.apply(ScalaReflection.scala:583)
at scala.collection.TraversableLike$$anonfun$flatMap$1.apply(TraversableLike.scala:241)
at scala.collection.TraversableLike$$anonfun$flatMap$1.apply(TraversableLike.scala:241)
at scala.collection.immutable.List.foreach(List.scala:381)
at scala.collection.TraversableLike$class.flatMap(TraversableLike.scala:241)
............

Ниже приводится код:

case class FireService(callNumber: String, callDate: java.time.LocalDate)
implicit val localDateEncoder: org.apache.spark.sql.Encoder[java.time.LocalDate] = org.apache.spark.sql.Encoders.kryo[java.time.LocalDate]

val fireServiceDf = df.map(row => {
val dateFormatter = java.time.format.DateTimeFormatter.ofPattern("MM/dd /yyyy")
FireService(row.getAs[String](0),  java.time.LocalDate.parse(row.getAs[String](4), dateFormatter))
})

Как мы можем определить сторонний кодировщик api для искры?

Обновить

Когда я создаю кодировщик для всего класса case, df.map.. преобразует объект в двоичный файл, как показано ниже:

implicit val fireServiceEncoder: org.apache.spark.sql.Encoder[FireService] = org.apache.spark.sql.Encoders.kryo[FireService]

val fireServiceDf = df.map(row => {
 val dateFormatter = java.time.format.DateTimeFormatter.ofPattern("MM/dd/yyyy")
 FireService(row.getAs[String](0), java.time.LocalDate.parse(row.getAs[String](4), dateFormatter))
})

fireServiceDf: org.apache.spark.sql.Dataset[FireService] = [value: binary]

Я ожидаю карту для FireService, но возвращаю двоичный файл карты.


person Harmeet Singh Taara    schedule 03.08.2016    source источник


Ответы (1)


Как говорится в последнем комментарии, «если класс содержит поле Bar, вам понадобится кодировщик для всего объекта». Вам необходимо предоставить неявный кодировщик для самого FireService; в противном случае Spark создаст его для вас, используя SQLImplicits.newProductEncoder[T <: Product : TypeTag]: Encoder[T]. По типу видно, что он не использует никаких implicit параметров кодировщика для полей, поэтому он не может использовать наличие localDateEncoder.

Spark можно изменить, чтобы справиться с этим, например используя библиотеку Shapeless или используя макросы напрямую; Не знаю, планируется ли это на будущее.

person Alexey Romanov    schedule 03.08.2016
comment
Привет, @Alexey, я понял вашу точку зрения, но я не понимаю точной причины, почему нам потребовалось полное средство форматирования объектов? - person Harmeet Singh Taara; 03.08.2016
comment
Японял твою точку зрения. Я также обновляю вопрос, потому что теперь мои данные преобразованы в двоичные. Когда я использую метку времени вместо LocalDate, схема данных строится как FireService, иначе как двоичный файл. - person Harmeet Singh Taara; 04.08.2016
comment
Задайте это как отдельный вопрос. В общем, не редактируйте вопрос, чтобы задать другой. - person Alexey Romanov; 04.08.2016
comment
@AlexeyRomanov У меня такая же проблема. У вас есть пример кода, как кодировать весь проект? Огромное спасибо! - person Rock; 10.08.2016