web-dev-qa-db-ja.com

ケースクラスを使用してJSONをエンコードすると、「データセットに格納されているタイプのエンコーダーが見つかりません」というエラーが表示されるのはなぜですか?

私は書きましたspark job:

object SimpleApp {
  def main(args: Array[String]) {
    val conf = new SparkConf().setAppName("Simple Application").setMaster("local")
    val sc = new SparkContext(conf)
    val ctx = new org.Apache.spark.sql.SQLContext(sc)
    import ctx.implicits._

    case class Person(age: Long, city: String, id: String, lname: String, name: String, sex: String)
    case class Person2(name: String, age: Long, city: String)

    val persons = ctx.read.json("/tmp/persons.json").as[Person]
    persons.printSchema()
  }
}

IDE main関数を実行すると、2つのエラーが発生します。

Error:(15, 67) Unable to find encoder for type stored in a Dataset.  Primitive types (Int, String, etc) and Product types (case classes) are supported by importing sqlContext.implicits._  Support for serializing other types will be added in future releases.
    val persons = ctx.read.json("/tmp/persons.json").as[Person]
                                                                  ^

Error:(15, 67) not enough arguments for method as: (implicit evidence$1: org.Apache.spark.sql.Encoder[Person])org.Apache.spark.sql.Dataset[Person].
Unspecified value parameter evidence$1.
    val persons = ctx.read.json("/tmp/persons.json").as[Person]
                                                                  ^

Spark Shellの場合、このジョブをエラーなしで実行できます。問題は何ですか?

16
Milad Khajavi

エラーメッセージは、EncoderPersonケースクラスを取得できないことを示しています。

Error:(15, 67) Unable to find encoder for type stored in a Dataset.  Primitive types (Int, String, etc) and Product types (case classes) are supported by importing sqlContext.implicits._  Support for serializing other types will be added in future releases.

ケースクラスの宣言をSimpleAppのスコープ外に移動します。

34
Developer

SimpleAppsqlContext.implicits._spark.implicits._を追加すると、同じエラーが発生します(順序は関係ありません)。

どちらかを削除することがソリューションになります:

val spark = SparkSession
  .builder()
  .getOrCreate()

val sqlContext = spark.sqlContext
import sqlContext.implicits._ //sqlContext OR spark implicits
//import spark.implicits._ //sqlContext OR spark implicits

case class Person(age: Long, city: String)
val persons = ctx.read.json("/tmp/persons.json").as[Person]

Spark 2.1.でテスト

面白いことに、同じオブジェクトを暗黙的に2回追加しても問題は発生しません。

4
Paul Leclercq

@Milad Khajavi

オブジェクトSimpleAppの外部にPersonケースクラスを定義します。また、main()関数内にimport sqlContext.implicits._を追加します。

2
Santhoshm