Каковы способы работы с вложенными классами дел в Spark? - PullRequest
0 голосов
/ 15 апреля 2020

У меня есть следующая структура для моих данных

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 для каждого набора столбцов, остается ли разница в производительности существенной?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...