首页 > 解决方案 > 有没有办法限制火花数据帧类型中的字符串长度?

问题描述

有没有办法为 spark Dataframe 中的字符串类型设置最大长度。我正在尝试读取一列字符串,获取最大长度并使该列的最大长度为最大长度。

有没有办法做到这一点 ?

标签: dataframeapache-spark

解决方案


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))

希望这可以帮助。


推荐阅读