基于對資料集和資料框的描述,我撰寫了這個非常簡短的測驗代碼,它可以作業。
import org.apache.spark.sql.functions._
val thing = Seq("Spark I am your father", "May the spark be with you", "Spark I am your father")
val wordsDataset = sc.parallelize(thing).toDS()
如果可行...為什么運行它會給我一個
錯誤:值 toDS 不是 org.apache.spark.rdd.RDD[org.apache.spark.sql.catalog.Table] 的成員
import org.apache.spark.sql.functions._
val sequence = spark.catalog.listDatabases().collect().flatMap(db =>
spark.catalog.listTables(db.name).collect()).toSeq
val result = sc.parallelize(sequence).toDS()
uj5u.com熱心網友回復:
toDS()不是的成員RRD[T]。歡迎來到 Scala 隱含的奇異世界,看起來什么都不是。
toDS()是 的成員DatasetHolder[T]。在SparkSession中,有一個名為 的物件implicits。當使用類似的運算式進入范圍時import sc.implicits._,呼叫的隱式方法rddToDatasetHolder可用于決議:
implicit def rddToDatasetHolder[T](rdd: RDD[T])(implicit arg0: Encoder[T]): DatasetHolder[T]
當您呼叫rdd.toDS()時,編譯器首先在RDD類及其所有超類中搜索一個被呼叫的方法toDS()。它沒有找到一個,所以它開始搜索范圍內所有兼容的隱式。這樣做時,它會找到rddToDatasetHolder接受RDD實體的方法并回傳具有toDS()方法的型別的物件。基本上,編譯器會重寫:
sc.parallelize(sequence).toDS()
進入
SparkSession.implicits.rddToDatasetHolder(sc.parallelize(sequence)).toDS()
現在,如果你看一下rddToDatasetHolder它自己,它有兩個引數串列:
(rdd: RDD[T])
(implicit arg0: Encoder[T])
Scala 中的隱式引數是可選的,如果您不顯式提供引數,編譯器會在范圍內搜索與所需引數型別匹配的隱式,并傳遞它找到或可以構造的任何物件。在這種特殊情況下,它會查找該Encoder[T]型別的實體。標準 Scala 型別有許多預定義的編碼器,但對于大多數復雜的自定義型別,不存在預定義的編碼器。
所以,簡而言之:預定義的存在Encoder[String]使得呼叫toDS()的實體成為可能RDD[String],但是預定義的缺失Encoder[org.apache.spark.sql.catalog.Table]使得不可能呼叫toDS()的實體RDD[org.apache.spark.sql.catalog.Table]。
順便說一句,包含具有方法SparkSession.implicits的隱式類。這就是運算式轉換為 column 實體的方式。StringToColumn$$"foo"Columnfoo
決議所有隱式引數和隱式轉換是編譯 Scala 代碼如此緩慢的原因。
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/492253.html
