我使用Datastax spark-cassandra-connector
访问Cassandra中的某些数据。
为了能够有效地访问我查询所需的所有数据,我必须使用joinWithCassandraTable
方法从一堆分区中获取数据。这给了我一个类com.datastax.spark.connector.rdd.CassandraTableScanRDD
的对象(或者类似的,测试我实际上只是使用标准sc.cassandraTable(ks, tbl)
方法来读取数据)。
问题是,我需要在结果对象上使用的所有方法都需要类org.apache.spark.sql.Dataset
的对象。
我已经做了很多搜索,并且找不到任何可以帮助的东西 - 我发现的最近的是this类似的问题,我不认为已经得到了充分的回答,因为它忽略了使用joinWithCassandraTable
来访问所有必要数据的推荐方法的用例。
我也是java和scala的新手,很抱歉,如果我有点慢。任何帮助都将受到大力赞赏,因为我现在已经陷入困境。
谢谢, AKHIL
答案 0 :(得分:3)
您可以做的是将您的RDD读入RDD [Row],然后将其更改为DataFrame。我们唯一的问题是我们还需要Schema。所以我们分两步完成。
首先,让我们从连接目标
以编程方式获取架构val schema = spark.read.cassandraFormat("dogabase", "test").load.schema
/**
schema: org.apache.spark.sql.types.StructType =
StructType(StructField(owner,StringType,true),
StructField(dog_id,IntegerType,true),
StructField(dog_age,IntegerType,true),
StructField(dog_name,StringType,true))
**/
然后我们可以从我们的Cassandra Driver中制作org.apache.spark.sql.Row
个对象
行。
import org.apache.spark.sql.Row
val joinResult =
sc.parallelize(Seq(Tuple1("Russ")))
.joinWithCassandraTable("test", "dogabase")
.map{ case(_, cassandraRow) => Row(cassandraRow.columnValues:_*)} //Unpack our Cassandra row values into a spark.sql.Row
现在我们有了一个架构和一个RDD [Row],我们可以使用spark会话的createDataFrame方法
val dataset = spark.createDataFrame(joinResult, schema)
dataset.show
/**
+-----+------+-------+--------+
|owner|dog_id|dog_age|dog_name|
+-----+------+-------+--------+
| Russ| 1| 10| cara|
| Russ| 2| 11|sundance|
+-----+------+-------+--------+
**/
只是因为你不相信我的DataFrame是数据集
dataset.getClass
Class[_ <: org.apache.spark.sql.DataFrame] = class org.apache.spark.sql.Dataset
某些Cassandra类型不是Spark Rows的有效基础,因此您可能需要转换它们。这可以通过编写快速转换功能来完成。不幸的是,SCC使用的内置转换构成了内部表示,因此我们无法使用这些转换。
def convertToSpark(element:Any): Any = {
case time: org.joda.time.LocalDate => time.toDateTimeAtStartOfDay().toDate //Convert to java.util.Date
case other => other
}
然后在制作行时
cassandraRow.columnValues.map(convertToSpark):_*