【发布时间】:2019-01-28 14:28:40
【问题描述】:
我需要将数据从 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 类型时),但是如何将它的值提取为字符串或可以聚合的东西。
我所能得到的就是在timestamp 列是Long 时完成此操作。
我的最终数据框应该看起来像 cassDF2,但新列 docID 包含 251929883819082018-12-09T12:25:25.904+0100event00001.withSa... 而不是 docID 中的 15147612000002512988381908event00001.withSa...
【问题讨论】:
标签: scala apache-spark