如何将RDD [CassandraRow]转换为DataFrame?

时间:2017-05-30 04:36:20

标签: scala apache-spark apache-spark-sql spark-streaming spark-cassandra-connector

目前,这就是我将Cassandrarow RDD转换为数据帧的方式:

val ssc = new StreamingContext(sc, Seconds(15))

val dstream = new ConstantInputDStream(ssc, ssc.cassandraTable("db", "table").select("createdon"))

import sqlContext.implicits._

dstream.foreachRDD{ rdd =>
    val dataframeJobs = rdd.map(w => (w.dataAsString)).map(_.split(":")).map(x =>(x(1))).map(_.split(" ")).map(x =>(x(1))).toDF("ondate")
}

正如您所看到的,我首先将cassandraRow rdd转换为字符串,然后映射到我想要的格式。我发现这个方法变得复杂,因为当rdd包含多个coloumns而不是一个(createdon)时,如示例所示。

还有其他替代方法可以将cassandraRow RDD转换为数据帧吗?

我的build.sbt如下:

scalaVersion := "2.11.8"

libraryDependencies ++= Seq(
  "com.datastax.spark" %% "spark-cassandra-connector" % "2.0.1",
  "org.apache.spark" %% "spark-core" % "2.0.2" % "provided",
  "org.apache.spark" %% "spark-sql" % "2.0.2",
  "org.apache.spark" %% "spark-streaming" % "2.0.2"
)

2 个答案:

答案 0 :(得分:0)

我想出了一种可以有效处理任意数量的coloumns的替代方法:

rdd.keyBy(row =>(row.getString(" createdon")))。map(x => x._1).toDF(" ondate")

答案 1 :(得分:0)

引用SparkContextFunctions的scaladoc(删除隐式参数):

  

cassandraTable [T](keyspace:String,table:String):CassandraTableScanRDD [T] 以CassandraRDD形式返回Cassandra表的视图。通过导入com.datastax.spark.connector._

,可以在SparkContext上使用此方法      

根据传递给cassandraTable的类型参数,每行都会转换为以下之一:

     
      
  • 一个CassandraRow对象(默认情况下,如果没有给出类型)
  •   
  • 包含列值的元组与CassandraRDD选择的列的顺序相同#select
  •   
  • 用户定义的类的对象,由适当的ColumnMapper填充
  •   

所以,我建议使用以下内容:

ssc.cassandraTable[String]("db", "table").select("createdon")

这应该为您提供了根据文档访问createdon的最简单方法。

我也想知道为什么你没有像Datasets中所描述的那样使用spark-cassandra-connector支持的DataFrame。这样你的代码可能会变得更简单。

您可以尝试使用Spark SQL的Structured Streaming替换Spark Streaming(几乎正式废弃):

  

结构化流是一个基于Spark SQL引擎的可扩展且容错的流处理引擎。您可以像表达静态数据的批处理计算一样表达流式计算。 Spark SQL引擎将负责逐步和连续地运行它,并在流数据继续到达时更新最终结果。

我不确定Cassandra Spark Connector是否支持它。