微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何定义处理参数化类型数据集的方法?

如何解决如何定义处理参数化类型数据集的方法?

我正在尝试定义一些函数,这些函数Datasets(类型化 DataFrames)作为输入并产生另一个作为输出,我希望它们足够灵活以处理参数化类型。在这个例子中,我需要一个列来表示用户的 ID,但如果该 ID 是 Int、Long、String 等,这对我的函数无关紧要。这就是为什么我的案例类有这个类型参数 {{ 1}}。

我起初尝试简单地编写我的函数并使用 A 而不是 Dataset

DataFrame

...但我收到此错误

import org.apache.spark.sql.Dataset

case class InputT[A](id: A,data: Long)
case class OutputT[A](id: A,dataA: Long,dataB: Long)

def someFunction[A](ds: Dataset[InputT[A]]): Dataset[OutputT[A]] = {
  ds.select().as[OutputT[A]] // suppose there are some transformations here
}

所以我尝试为我的类型提供一个编码器:

Unable to find encoder for type OutputT[A]. An implicit Encoder[OutputT[A]] is needed
to store OutputT[A] instances 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.

现在我收到此错误

import org.apache.spark.sql.Dataset
import org.apache.spark.sql.catalyst.encoders.ExpressionEncoder

case class InputT[A](id: A,dataB: Long)

implicit def enc[A]: Encoder[InputT[A]] = implicitly(ExpressionEncoder[OutputT[A]])

def someFunction[A](ds: Dataset[InputT[A]]): Dataset[OutputT[A]] = {
  ds.select().as[OutputT[A]] // suppose there are some transformations here
}

如果代码与上面相同,但没有类型参数(例如,使用 No TypeTag available for OutputT[A] 而不是 String),则没有错误

尽可能避免使用 A 魔法,我应该怎么做才能解决这个问题?是否有可能通过 import spark.implicits._ 实现这种级别的灵活性?

解决方法

如果您选中 Scaladoc,您会看到 as 需要一个 Encoder,因此您只需要将其添加到范围。

def someFunction[A](ds: Dataset[InputT[A]])(implicit ev: Encoder[[OutputT[A]]): Dataset[OutputT[A]] = {
  ds.select().as[OutputT[A]]
}

此外,您可能还想看看 Where does Scala look for implicits

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。