Spark中从Struct字符串如何快速创建Schema

发布于 2022-09-11 21:40:08 字数 2440 浏览 26 评论 0

在使用Spark 2.4.0的一个新方法schema_of_json,主要是用来从json格式字符串中推断Schema的,方法有两个重载,源码如下

/**
 * Parses a JSON string and infers its schema in DDL format.
 *
 * @param json a JSON string.
 *
 * @group collection_funcs
 * @since 2.4.0
 */
def schema_of_json(json: String): Column = schema_of_json(lit(json))

/**
 * Parses a JSON string and infers its schema in DDL format.
 *
 * @param json a string literal containing a JSON string.
 *
 * @group collection_funcs
 * @since 2.4.0
 */
def schema_of_json(json: Column): Column = withExpr(new SchemaOfJson(json.expr))

我不知道怎么使用schema_of_json(json: Column)这个方法,我通过如下测试报错:

scala> df.select(schema_of_json($"col"))
org.apache.spark.sql.AnalysisException: cannot resolve 'schemaofjson(`col`)' due to data type mismatch: The input json should be a string literal and not null; however, got `col`.;;

看错误信息是需要传入一个字符串参数,所以如图测试了

clipboard.png

它的Row是一个String对象,我现在能想到的就是用take取出一行,然后通过字符串分隔,取出各个Column的列,然后重构StructType。像这样

scala> val str = df.select(schema_of_json(df.take(1)(0).get(0).toString).alias("schema")).select(regexp_extract($"schema","struct<(.*?)>",1)).take(1)(0).getAs[String](0)
str: String = cardno:string,cardtype:string,flag:string,times:string,userid:string

scala> val columns = str.split(",").map(x=>x.split(":")).map(x=>x(0))
columns: Array[String] = Array(cardno, cardtype, flag, times, userid)

scala> var schema = (new StructType)
schema: org.apache.spark.sql.types.StructType = StructType()

scala> columns.map(x=>{schema = schema.add(x,StringType,true)})
res154: Array[Unit] = Array((), (), (), (), ())

scala> schema
res159: org.apache.spark.sql.types.StructType = StructType(StructField(cardno,StringType,true), StructField(cardtype,StringType,true), StructField(flag,StringType,true), 
StructField(times,StringType,true), StructField(userid,StringType,true))

但是StructType有一个simpleString方法,返回的就是上图中的值

scala> schema.simpleString
res160: String = struct<cardno:string,cardtype:string,flag:string,times:string,userid:string>

虽然我上面写的可行,但要是遇到那种嵌套的复杂的Schema,这样写就很复杂。想问下有什么快速把struct<xxx>字符串转化成StructType的方法吗?

或者有什么其他方法解析json格式的字符串吗?我这里使用的Structured Streaming,创建的是df,而需求是不能提前确定Schema长什么样,需要的是从消息字符串中去推断。

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文