【问题标题】:scala joinWithCassandraTable result to dataframescala joinWithCassandraTable 结果到数据框
【发布时间】:2020-11-06 10:31:39
【问题描述】:

我正在使用 Datastax spark-Cassandra-connector 访问 Cassandra 中的一些数据。 我的要求是将 RDD 与 Cassandra 表连接,获取结果并将其存储在 hive 表中。

我正在使用 joinWithCassandraTable 加入 cassadra 表。加入后,产生的 RDD 如下所示

com.datastax.spark.connector.rdd.CassandraJoinRDD[org.apache.spark.sql.Row, 
com.datastax.spark.connector.CassandraRow] = 
CassandraJoinRDD[17] at RDD at CassandraRDD.scala:19

我尝试了以下步骤来转换为数据框,但没有一种方法有效。

val data=joinWithRDD.map{
   case(_, cassandraRow) =>    Row(cassandraRow.columnValues:_*)
}

sqlContext.createDataFrame(data,schema)

我遇到了错误

java.lang.ClassCastException: cannot assign instance of
   scala.collection.immutable.List$SerializationProxy to field 
   org.apache.spark.rdd.RDD.org$apache$spark$rdd$RDD$$dependencies_ of 
   type scala.collection.Seq in instance of org.apache.spark.rdd.MapPartitionsRDD

您能帮我将joinWithCassandraTable 转换为数据框吗?

【问题讨论】:

    标签: apache-spark cassandra spark-cassandra-connector


    【解决方案1】:

    如我所见,您在联接的左侧使用数据框。我建议不要使用使用 RDD API 的 joinWithCassandraTable,而是使用 has support for join in the Dataframe API 的 Spark Cassandra 连接器 2.5.x(2.5.1 是最新的),并直接使用它。真的很简单,你只需要用--conf spark.sql.extensions=com.datastax.spark.connector.CassandraSparkExtensions开始你的工作来激活这个functionality,之后,代码就只是在数据帧上使用普通的连接:

    val parsed = ...some dataframe...
    val cassandra = spark.read
      .format("org.apache.spark.sql.cassandra")
      .options(Map("table" -> "stock_info", "keyspace" -> "test"))
      .load
    
    // we can use left join to detect what data is incorrect - if we don't have some data in the
    // Cassandra, then symbol field will be null, so we can detect such entries, and do something with that
    // we can omit the joinType parameter, in that case, we'll process only data that are in the Cassandra
    val joined = parsed.join(cassandra, cassandra("symbol") === parsed("ticker"), "left")
       .drop("ticker")
    

    带有自述文件的完整源代码是here

    【讨论】:

    • 要使用 Spark Cassandra 2.5x,我需要 spark 2.4 及更高版本。但是我使用的是 spark2.3 所以不能使用这个功能。我想玩一下 joinWithCassandraTable 结果。将此 rdd 转换为数据框的最佳方法是什么?
    • 我刚刚用 Spark 2.3.2 测试了 2.5.1,它运行良好 - 我在输出中有 Cassandra Direct Join... 如果它不适合你,那么让我们尝试做其他方式。也许你可以为你的表数据定义一个案例类,并使用joinWithCassandraTable[CaseClass](...
    • 谢谢,Alex:使用案例类后,我的结果看起来像。 com.datastax.spark.connector.rdd.CassandraJoinRDD[org.apache.spark.sql.Row,String] = CassandraJoinRDD[86] at RDD at CassandraRDD.scala:19 这里我从 cassandra 表中只选择了一列。我有将近 100 列。例如: Array[(org.apache.spark.sql.Row, String)] = Array(([123456],F2)) 。我怎样才能转换成数据框?或者有什么简单的方法可以提取每个列的值并存储到一个配置单元表中?
    • 你需要通过.map将其转成平面RDD(最好转成case类),然后再将RDD转成dataframe
    • 对不起..我可能遗漏了一些基本的东西。这就是我的 RDD 看起来像使用 joinWithCassandraTable 的 aftet。数组[(org.apache.spark.sql.Row, com.datastax.spark.connector.CassandraRow)] = 数组(([234567],CassandraRow{event: gg}))。这就是我如何扁平化 RDD .val data=joinWithRDD_take.map{case(, cassandraRowa) => Row(cassandraRowa.columnValues:*)} case class schema(sv_event_type: String) val data2=sqlContext .createDataFrame(data.map{case Row(sv_event_type: String) => schema(sv_event_type.trim) }) 。但这不起作用。你能帮忙把RDD弄平吗?
    猜你喜欢
    • 2018-03-09
    • 1970-01-01
    • 1970-01-01
    • 2017-06-22
    • 1970-01-01
    • 2019-11-19
    • 2021-01-12
    • 2018-01-02
    • 2016-10-06
    相关资源
    最近更新 更多