2016-08-03 23 views
10
için bir kodlayıcı bulunamadı

Apache Spark 2.0 kullanıyorum ve DetaSet için şema için case class oluşturuyorum. i java.time.LocalDate için, How to store custom objects in Dataset? göre özel kodlayıcı tanımlamak çalışıyorum zaman ben şu istisna var: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) 
............ 

ardından kod gereğidir:

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)) 
}) 

biz kıvılcım için üçüncü taraf API en kodlayıcı tanımlayabilirsiniz nasıl?

Güncelleme

i bütün vaka sınıf için kodlayıcı oluşturduğunuzda, df.map.. aşağıda ikili içine nesneyi, harita:

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] 

Ben FireService için harita bekliyorum ama haritanın ikili dönmek .

cevap

4

Son yorum olarak "sınıf bir alan içeriyorsa, bir nesne için kodlayıcıya ihtiyacınız var." FireService'un kendisi için örtülü bir Enkoder sağlamanız gerekir; Aksi halde Spark, SQLImplicits.newProductEncoder[T <: Product : TypeTag]: Encoder[T]'u kullanarak sizin için bir tane oluşturur. Alanlar için implicit Enkoder parametrelerini kullanmadığı türden görebilirsiniz, böylece localDateEncoder'un varlığını kullanamaz.

Bu ör. Shapeless kütüphanesini kullanarak veya doğrudan makroları kullanarak; Gelecekte planın bu olup olmadığını bilmiyorum.

+0

Hey @Alexey, nedenini tam olarak anlamıyorum, neden tam nesne biçimlendiriciye ihtiyacımız vardı? –

+0

Amacınızı aldım. Soruyu da güncelliyorum çünkü şimdi verilerim İkili'ye dönüştürüldü. LocalDate yerine Timestamp kullandığımda, veri merkezi FireService'i bir ikili olarak yapılandırır. –

+0

Lütfen bunu ayrı bir soru olarak sorun. Genel olarak, farklı bir soru sormak için bir soru düzenlemeyin. –

İlgili konular