У меня есть следующая структура для моих данных
Request
|-- id: int
|-- suggestion: Suggestion
Suggestion
|-- details: Map[String, String]
|-- attributes: List[String]
Если у меня есть набор данных запроса, как я могу работать с предложением и передавать его, чтобы я мог создавать модульные методы для различных вариантов использования?
Возможные варианты - использование UDF и функций карты.
С UDF это было бы что-то вроде
val df1 = request.withColumn("param1", udf1(col("suggestion"))
.withColumn("param2", udf2(col("suggestion"))
val df2 = request.withColumn("param1", udf3(col("suggestion"))
.withColumn("param2", udf4(col("suggestion"))
def udf1 : (Suggestion) => Long = (suggestion : Suggestion) => {
suggestion.attributes.size
}
Но это ломается с ошибкой
GenericRowWithSchema cannot be cast to case class
Так что мы не можем напрямую передать класс case в UDF и только так читать его как объект Row, но это означало бы, что метод, работающий с объектом Row, должен знать внутренний порядок класса Предложение, поскольку он не может получить доступ к атрибутам по их имени и только по индексу.
def udf1 : (Row) => Long = (suggestion : Row) => {
suggestion.getList(1).size
}
Я пытался использовать кодировщики для преобразования строки в предложение, но не смог этого сделать.
Нет ли возможности использовать UDF для описанного выше варианта использования?
Эффективно ли использование функций карты? или есть существенная разница в производительности для пользовательских функций и карт? Я понимаю, что Map десериализует весь ряд сразу, и это может ухудшить производительность.
Но если мы читаем все столбцы запроса и альтернативой является создание отдельных UDF для каждого набора столбцов, остается ли разница в производительности существенной?