Есть ли способ ограничения длины строки в типе кадра данных искры? - PullRequest
1 голос
/ 20 января 2020

Есть ли способ установить максимальную длину для типа строки в кадре данных искры. Я пытаюсь прочитать столбец строки, получить максимальную длину и сделать этот столбец типа String максимальной длины максимальной длины.

Есть ли способ сделать это?

1 Ответ

1 голос
/ 21 января 2020

В Spark нет типа строки с «ограниченной длиной». Вы можете добиться такого поведения с помощью преобразования.

Если вы хотите, чтобы длинные строки усекались, вы можете сделать это с помощью чего-то вроде:

val colName = "my_col"
val c = col(colName)
df.select(
  when(length(c) > maxLen, substring(c, 1, maxLen)).otherwise(c).as(colName)
)

Если вы хотите, чтобы длинные строки генерировали среду выполнения ошибка, это немного сложнее, особенно если вы хотите читаемые сообщения об ошибках. Вы должны создать UDF, который выдает ошибку, например,

/** Exception thrown by stop() UDF */
case class StopExecutionException(message: String) extends RuntimeException(message)

/**
 * Stops execution with a user defined error message.
 * This is useful when you want to stop processing due to an exceptional condition,
 * for example, an illegal value was encountered in the data.
 *
 * @param message the message of the exception: allows for data-driven exception messages
 * @tparam A return type to avoid analysis errors
 * @return the function never returns
 * @throws StopExecutionException
 */
def stop[A](message: String): A = {
  throw StopExecutionException(message)
}

val colName = ...
val c = col(colName)
df.select(
  when(length(c) <= maxLen, c)
    .otherwise {
      val stopUdf = udf(stop[String] _)
      stopUdf(concat(lit(s"Column $colName exceeds max length $maxLength: "), c))
    }
    .as(colName)
)

И последнее, но не менее важное, если вы хотите передавать метаданные maxLength в базу данных, чтобы он выбирал оптимальный тип хранения для столбцов коротких строк, Вы должны добавить метаданные в столбец данных, например,

val metadata = new MetadataBuilder().putLong("maxlength", maxLen).build()
df.select(c.as(colName, metadata))

Надеюсь, это поможет.

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