Iskra 是一个围绕 Apache Spark API 的 Scala 3 包装器库,它允许编写类型安全、无样板但仍然高效的 Spark 代码。
从 3.2.0 版本开始,Spark 也针对 Scala 2.13 进行交叉编译,这开辟了一种从 Scala 3 代码使用 Spark 的方法,因为 Scala 3 项目可以依赖于 Scala 2.13 工件。
但是,当尝试调用需要 Spark Encoder
类型的隐式实例的方法时,可能会遇到问题。 Encoder
实例的派生依赖于给定类型的TypeTag
的存在。然而,Scala 3 编译器不再生成TypeTag
(并且没有计划支持这一点),因此在大多数情况下无法自动合成Encoder
的实例。
Iskra 试图通过使用自己的编码器(与 Spark 的Encoder
类型无关)来解决这个问题,这些编码器是使用 Scala 3 的新元编程 API 生成的。
Iskra 提供了围绕DataFrame
的瘦(但强类型)包装器,它在编译时跟踪列的类型和名称,但让 Catalyst 在运行时执行所有优化。
Iskra 使用结构类型而不是案例类作为数据模型,这为我们提供了很大的灵活性(在添加/删除/重命名列时无需显式定义新的案例类!),但当我们尝试引用不存在或无法在给定上下文中使用的列。
//> using lib " org.virtuslab::iskra:0.0.3 "
scala-cli repl --dep org.virtuslab::iskra:0.0.3
build.sbt
中: libraryDependencies + = " org.virtuslab " %% " iskra " % " 0.0.3 "
Iskra 是使用 Scala 3.1.3 构建的,因此它与 Scala 3.1.x 和更新的次要版本兼容(从 3.2.0 开始,您将获得 REPL 和 Metals 中列名称的代码补全!)。 Iskra 间接依赖于 Spark 3.2.0。
import org . virtuslab . iskra . api . *
given spark : SparkSession =
SparkSession
.builder()
.master( " local " )
.appName( " my-spark-app " )
.getOrCreate()
Seq
上使用toTypedDF
扩展方法,例如 Seq ( Foo ( 1 , " abc " ), Foo ( 2 , " xyz " )).toTypedDF
typed
扩展方法,例如df.typed[ Foo ]
如果由于某种原因您需要返回非类型化数据帧的不安全世界,只需在类型化数据帧上调用.untyped
即可。
该库旨在尽可能地最大程度地类似于 Spark 的原始 API(例如,通过使用相同的方法名称等),尽管试图使代码感觉更像常规 Scala,而无需不必要的样板文件并添加一些其他语法改进。
最重要的区别:
$.foo.bar
而不是$"foo.bar"
或col("foo.bar")
来引用列(还带有指定数据帧别名的前缀,以防歧义)。必要时使用反引号,例如$.`column with spaces`
。.select(...)
或.select{...}
内部,您应该返回命名列或命名列元组的内容。由于 Scala 语法的工作原理,您可以简单地编写.select($.x, $.y)
而不是select(($.x, $.y))
。使用大括号,您可以计算中间值,例如.select {
val sum = ($.x + $.y).as( " sum " )
($.x, $.y, sum)
}
foos.innerJoin(bars).on($.foos.barId === $.bars.id).select(...)
foos
和bars
的别名是自动推断的该项目是使用 scala-cli 构建的,因此只需使用带有.
像scala-cli compile .
或scala-cli test .
。
有关Usage
部分的最新版本,请参阅此处