从DataFrame创建嵌套的case类实例

时间:2018-02-23 01:28:01

标签: scala apache-spark cassandra spark-dataframe case-class

我有两个案例类:

case class Inline_response_200(
  nodeid: Option[String],
  data: Option[List[ReadingsByEpoch_data]]
)

case class ReadingsByEpoch_data(
  timestamp: Option[Int],
  value: Option[String]
)

我有一张Cassandra表,其中包含nodeid|timestamp|value等数据。基本上,每个nodeid都有多个timestamp - value对。

我想要做的就是创建Inline_response_200的实例及其ReadingsByEpoch_data的正确列表,以便杰克逊可以将它们正确地序列化为Json。

我已经尝试了

val res = sc.cassandraTable[Inline_response_200]("test", "taghistory").limit(100).collect()

但是我收到了这个错误

  

java.lang.IllegalArgumentException:无法将com.wordnik.client.model.Inline_response_200中的构造函数参数数据映射到test.taghistory列

总的来说,因为我的Cassandra表中没有列data。但是,我怎样才能正确创建实例?

Cassandra表看起来像这样:

CREATE TABLE test.taghistory (
nodeid text,
timestamp text,
value text,
PRIMARY KEY (nodeid, timestamp)
) WITH CLUSTERING ORDER BY (timestamp DESC)

修改
根据Alex Ott的建议:

val grouped = data.groupByKey.map {
  case (k, v) =>
    Inline_response_200(k.getString(0), v.map(x => ReadingsByEpoch_data(x.getInt(1), x.getString(2))).toList)
}
grouped.collect().toList

我已经关闭但还没有。这给了我期望的格式,但是它为每条记录创建了一个Inline_response_200实例:

[{"nodeid":"Tag3","data":[{"timestamp":1519411780,"value":"80.0"}]},{"nodeid":"Tag3","data":[{"timestamp":1519411776,"value":"76.0"}]}]  

在这个例子中,我需要有一个nodeid键和一个包含两个时间戳值对的数组,如下所示:

[{"nodeid":"Tag3","data":[{"timestamp":1519411780,"value":"80.0"},{"timestamp":1519411776,"value":"76.0"}]}]`  

也许我是以错误的方式分组?

1 个答案:

答案 0 :(得分:1)

如果你的数据库中有nodeid|timestamp|value这样的数据(是的,根据模式),你不能直接将它映射到你从表中创建读取数据的结构RDD:

val data = sc.cassandraTable[(String,String,Option[String])]("test", "taghistory")
     .select("nodeid","timestamp","value").keyBy[String]("nodeid")

然后在该对RDD&上使用groupByKey将其转换为您需要的结构。转换为您需要的Inline_response_200类,如下所示:

val grouped = data.groupByKey.map{case (k,v) => Inline_response_200(k,
       v.map(x => ReadingsByEpoch_data(x._2, x._3)).toList)}
grouped.collect