将时间戳列与字符串列连接

时间:2019-01-28 14:28:41

标签: scala apache-spark

我需要将数据从Cassandra推送到Elasticsearch。从cassandra加载了数据帧,但是名为timestamp的列为Long格式,因此我需要将其更改为timestamp以便更“易于阅读”, :

val cassDF2 = spark.createDataFrame(rawCass).withColumn("timestamp", ($"timestamp").cast(TimestampType))

数据框现在看起来像:

+--------------------+--------------------+-------------+--------------------+--------------------+
|             eventID|           timestamp|       userID|           sessionID|            fullJson|
+--------------------+--------------------+-------------+--------------------+--------------------+
|event00001.withSa...| 2018-11-15 09:00...|2512988381908|  WITH_EVENTS_IMPORT|{"header": {"appI...|
|event00002.withSa...| 2018-11-15 09:00...|2512988381908|WITH_EVENTS_SESSI...|{"body": {}, "hea...|
|event00003.withPa...| 2018-11-15 09:00...|2006052984315|  WITH_EVENTS_IMPORT|{"header": {"appI...|
+--------------------+--------------------+-------------+--------------------+--------------------+

现在,我需要将3列(seesionID, userID and timestamp)连接成一个新列(docID)并将其推送到ES:

  // concatStrings function
  val concatStrings = udf((userID: String, timestamp: String, eventID: String) => {userID + timestamp + eventID})

  // create column docID
  val cassDF = cassDF2.withColumn("docID", concatStrings($"userID", $"timestamp", $"eventID"))

获取错误:

  

org.apache.spark.sql.AnalysisException:“时间戳记”不是数字   柱。聚合功能只能应用于数字列。

我知道timestamp是现在调用.cast之后的对象,并且无法像以前一样(当其为Long类型时进行聚合),但是如何将其值提取为String或其他内容可以汇总的内容。

我所能获得的就是在timestamp列为Long时完成此操作。

我的最终数据框应该看起来像cassDF2,但新列docID包含251929883819082018-12-09T12:25:25.904+0100event00001.withSa...而不是15147612000002512988381908event00001.withSa...中的docID

1 个答案:

答案 0 :(得分:2)

不需要UDF。您可以使用内置方法concat将各列组合在一起,包括具有特定日期格式的字符串格式timestamp列,如下所示:

import spark.implicits._
import org.apache.spark.sql.functions._
import java.sql.Timestamp

val df = Seq(
  ("1001", Timestamp.valueOf("2018-11-15 09:00:00"), "Event1"),
  ("1002", Timestamp.valueOf("2018-11-16 10:30:00"), "Event2")
).toDF("userID", "timestamp", "eventID")

val dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSSZ"

df.
  withColumn("docID", concat($"userID", date_format($"timestamp", dateFormat), $"eventID")).
  show(false)
// +------+-------------------+-------+--------------------------------------+
// |userID|timestamp          |eventID|docID                                 |
// +------+-------------------+-------+--------------------------------------+
// |1001  |2018-11-15 09:00:00|Event1 |10012018-11-15T09:00:00.000-0800Event1|
// |1002  |2018-11-16 10:30:00|Event2 |10022018-11-16T10:30:00.000-0800Event2|
// +------+-------------------+-------+--------------------------------------+