Spark Dataframe / SQL - 复杂丰富嵌套数据

时间:2018-01-06 17:30:18

标签: apache-spark apache-spark-sql spark-dataframe databricks

上下文

我在数据框输入中有一个事件源数据的示例,如下所示。

SOURCE

enter image description here

其中eventOccurredTime是String类型。这是来源,我想保留它的原始字符串形式(纳秒)

我想使用该字符串来增加一些额外的日期/时间类型数据以供下游使用。下面是一个例子

TARGET

enter image description here

现在我可以在数据帧上执行一些spark sql,如下所示,以获得我想要的结果:

import org.apache.spark.sql.DataFrame

def transformDF(): DataFrame = {
  spark.sql(
   s"""
    SELECT 
      id,
      struct(
        event.eventCategory,
        event.eventName,
        event.eventOccurredTime,
        struct (
          CAST(date_format(event.eventOccurredTime,"yyyy-MM-dd'T'HH:mm:ss.SSS") AS TIMESTAMP) AS eventOccurredTimestampUTC,
          CAST(date_format(event.eventOccurredTime,"yyyy-MM-dd'T'HH:mm:ss.SSS") AS DATE) AS eventOccurredDateUTC,
          unix_timestamp(substring(event.eventOccurredTime,1,23),"yyyy-MM-dd'T'HH:mm:ss.SSS") * 1000  AS eventOccurredTimestampMillis,
          datesDim.dateSeq AS eventOccurredDateDimSeq
        ) AS eventOccurredTimeDim,

注意:这是一个片段,对于完整的事件,我必须在这个长SQL中显式执行20次20字符串日期

需要注意的一些事项:

unix_timestamp(substring(event.eventOccurredTime,1,23)

上面我发现我必须对具有纳米精度的日期进行子串,否则将返回null,因此子字符串

xDim.xTimestampUTC
xDim.xDateUTC
xDim.xTimestampMillis
xDim.xDateDimSeq

上面是4个嵌套的xDim结构字段的模式/命名约定,它们存在于预定义的spark模式中,json被用来创建源数据帧。

 datesDim.dateSeq AS eventOccurredDateDimSeq 

要获得上述' eventOccurredDateDimSeq'字段,我需要加入日期维度表' datesDim' (带有每小时颗粒的静态),其中dateSeq是'键'其中此日期属于每小时桶,其中datesDim.UTC定义为小时

LEFT OUTER JOIN datesDim ON
      CAST(date_format(event.eventOccurredTime,"yyyy-MM-dd'T'HH:00:00") AS TIMESTAMP) = datesDim.UTC

该表在spark集群中是全局可用的,因此应该快速查找,但我需要对有效负载中的每个日期丰富进行此操作,它们将具有不同的日期。

dateDimensionDF.write.mode("overwrite").saveAsTable("datesDim")

一般架构模式是,如果字段名称为字符串日期:

x 

..有一个&x 39; xDim' struct equiv,紧跟在下面的架构顺序中,如下所述。

xDim.xTimestampUTC
xDim.xDateUTC
xDim.xTimestampMillis
xDim.xDateDimSeq

正如片段中所提到的,虽然在上图中我只是展示了“eventOccuredTime'在上面,通过模式中有更多这些,在较低级别,也需要应用相同的转换模式。

问题:

所以我有一个spark sql(代码片段的完整monty)为1个事件类型执行此操作,并且它是一个大的,显式的SQL语句,它应用了我显示的时间函数和连接),但这是我的问题我需要帮助。

因此,我想尝试创建一个更通用的,功能导向的可重用解决方案,该解决方案遍历嵌套数据框并应用此转换模式,如上所述'

如何定义'它需要的位置'?

也许命名约定是一个好的开始 - 遍历DF,查找具有xDim(' Dim'后缀)模式的任何结构字段,并使用' x'字段作为输入,并按照所描述的命名模式填充xDim。*值?

如何在函数中最好地加入datesDim注册表(它的静态记忆),以便它执行?

解决方案吗

认为需要一个或多个UDF(我们使用Scala),可能单独使用或作为SQL中的片段,但不确定。我认为确保DatesDim查找执行是关键。

或许还有另一种方式?

注意:我正在使用Dataframes / SparkSQL而不是数据集,但每个欢迎选项?

Databricks

注意:实际上我实际上是使用数据库平台,所以对于SQL'高阶函数'中的那些经文。在Dbricks

https://docs.databricks.com/spark/latest/spark-sql/higher-order-functions-lambda-functions.html

....这里有一个灵活的选项,使用' TRANSFORM'作为SQL HOF(可能需要注册一个实用程序UDF并使用它与转换)?

太棒了,感谢火花社区的帮助!对不起,这是设置场景的长篇文章。

0 个答案:

没有答案