2016-08-05 18 views
5

Hãy nói rằng tôi có một Spark Dataset như thế này:Spark Dataset và java.sql.Date

scala> import java.sql.Date 
scala> case class Event(id: Int, date: Date, name: String) 
scala> val ds = Seq(Event(1, Date.valueOf("2016-08-01"), "ev1"), Event(2, Date.valueOf("2018-08-02"), "ev2")).toDS 

Tôi muốn tạo ra một mới Dataset với chỉ có tên và ngày lĩnh vực. Theo như tôi thấy, tôi có thể sử dụng ds.select() với TypedColumn hoặc tôi có thể sử dụng ds.select() với Column và sau đó chuyển đổi DataFrame thành Dataset.

Tuy nhiên, tôi không thể chọn tùy chọn cũ làm việc với loại Date. Ví dụ:

scala> ds.select($"name".as[String], $"date".as[Date]) 
<console>:31: error: Unable to find encoder for type stored in a Dataset. Primitive types (Int, String, etc) and Product types (case classes) are supported by importing spark.implicits._ Support for serializing other types will be added in future releases. 
       ds.select($"name".as[String], $"date".as[Date]) 
                ^

Các tùy chọn sau hoạt động:

scala> ds.select($"name", $"date").as[(String, Date)] 
res2: org.apache.spark.sql.Dataset[(String, java.sql.Date)] = [name: string, date: date] 

Có cách nào để chọn Date lĩnh vực từ Dataset mà không đi đến DataFrame và trở lại?

Trả lời

4

Đã bashing đầu chống lại các vấn đề như thế này cả ngày. Tôi nghĩ rằng bạn có thể giải quyết vấn đề của mình với một dòng:

implicit val e: Encoder[(String, Date)] = org.apache.spark.sql.Encoders.kryo[(String,Date)] 

Ít nhất điều đó đã làm việc cho tôi.

EDIT

Trong những trường hợp này, vấn đề là đối với hầu hết Dataset hoạt động, Spark 2 đòi hỏi một Encoder lưu trữ thông tin schema (có lẽ cho việc tối ưu). Thông tin lược đồ có dạng của một tham số ngầm định (và một bó của các hoạt động Dataset có loại tham số ngầm này).

Trong trường hợp này, OP tìm thấy sơ đồ chính xác cho java.sql.Date nên các công việc sau:

implicit val e = org.apache.spark.sql.Encoders.DATE 
+2

này không trực tiếp giải quyết vấn đề, nhưng nó đã cho tôi đi đúng hướng. Sử dụng 'implicit val encodeDate = org.apache.spark.sql.Encoders.DATE' giải quyết vấn đề. Tôi không chắc tại sao điều đó không được xử lý bởi các implicit mặc định. –