2016-08-03 2 views
10

Я использую Apache Spark 2.0 и создаю case class для ссылки на схему для DetaSet. Когда я пытаюсь определить пользовательский кодировщик согласно How to store custom objects in Dataset?, для java.time.LocalDate я получил следующее исключение:Apache Spark 2.0: java.lang.UnsupportedOperationException: Нет кодера для 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 третьего для искры?

Update

Когда я создать кодер для всего класса случае, 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, но возвращать двоичную карту ,

ответ

4

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

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

+0

Эй, @ Алексей, я понял, что у меня нет точной причины, почему нам нужен полный объект форматирования? –

+0

У меня есть точка. Я также обновляю вопрос, потому что теперь мои данные преобразуются в двоичные. Когда я использую Timestamp вместо LocalDate, dataschema строит как FireService иначе как двоичный. –

+0

Пожалуйста, задайте этот вопрос как отдельный вопрос. В общем, не редактируйте вопрос, чтобы задать другой вопрос. –

 Смежные вопросы

  • Нет связанных вопросов^_^