将columnNames动态传递给cassandraTable()。select()

时间:2016-08-04 22:00:03

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

我在运行时读取文件的查询并在SPark + Cassandra环境中执行它。

我执行:
sparkContext.cassandraTable.("keyspaceName", "colFamilyName").select("col1", "col2", "col3").where("some condition = true")

在FIle中查询:

  

选择col1,col2,col3   来自keyspaceName.colFamilyName    其中somecondition = true

这里Col1,col2,col3可以根据从文件解析的查询而有所不同。

问题:
如何从查询中选择columnName并将它们传递给select()和runtime。

我尝试了很多方法:
1.最愚蠢的事情(显然会引起错误) -

var str = "col1,col2,col3"
var selectStmt = str.split("\\,").map { x => "\"" + x.trim() + "\"" }.mkString(",")
var queryRDD = sc.cassandraTable().select(selectStmt)

欢迎任何想法。

附注:
1.我不想使用cassandraCntext,因为它将在下一个realase(https://docs.datastax.com/en/datastax_enterprise/4.5/datastax_enterprise/spark/sparkCCcontext.html)中被删除/删除 我在上     - 一个。斯卡拉2.11
     - b。火花卡桑德拉 - connector_2.11:1.6.0-M1
    - C。 Spark 1.6

1 个答案:

答案 0 :(得分:4)

使用Cassandra Connector

您的用例听起来好像您实际上想要使用CassandraConnector个对象。这些使您可以直接访问每个ExecutorJVM会话池,非常适合执行随机查询。这最终会比为每个查询创建RDD更有效。

这看起来像

rddOfStatements.mapPartitions( it => 
  CassandraConnector.withSessionDo { session => 
    it.map(statement => 
      session.execute(statement))})

但您最有可能希望使用executeAsync并单独处理期货以获得更好的效果。

以编程方式指定cassandraTable

中的列

select方法需要ColumnRef*,这意味着您需要传入一定数量的ColumnRef s。通常会有来自String - >的隐式转换。 ColumnRef这就是为什么你只能传入一个var-args的字符串。

这里有点复杂,因为我们想要传递另一种类型的var args,所以我们最终得到双重隐含,Scala不喜欢这样。

因此我们将ColumnName个对象作为varargs(:_ *)

传递
========================================
 Keyspace: test
========================================
 Table: dummy
----------------------------------------
 - id                      : java.util.UUID                                                                   (partition key column)
 - txt                     : String


val columns = Seq("id", "txt")
columns: Seq[String] = List(id, txt)

//Convert the strings to ColumnNames (a subclass of ColumnRef) and treat as var args
sc.cassandraTable("test","dummy")
  .select(columns.map(ColumnName(_)):_*)
  .collect      

Array(CassandraRow{id: 74f25101-75a0-48cd-87d6-64cb381c8693, txt: hello world})

//Only use the first column
sc.cassandraTable("test","dummy")
  .select(columns.map(ColumnName(_)).take(1):_*)
  .collect

Array(CassandraRow{id: 74f25101-75a0-48cd-87d6-64cb381c8693})

//Only use the last column        
sc.cassandraTable("test","dummy")
  .select(columns.map(ColumnName(_)).takeRight(1):_*)
  .collect

Array(CassandraRow{txt: hello world})