apache-spark – 对Spark SQL查询返回的行的非序数访问

在Spark文档中,声明Spark SQL查询的结果是SchemaRDD.这个SchemaRDD的每一行都可以通过序数访问.我想知道是否有任何方法可以使用案例类的字段名称来访问列,在这些字段名称的基础上构建SQL查询.我感谢case类与结果没有关联的事实,特别是如果我选择了单独的列和/或别名它们:但是,通过名称而不是序数访问字段的某种方式会很方便. 最佳答案 一种简单的方法是在生成的SchemaRDD上使用“语言集成”选择方法来选择所需的列 – 这仍然为您提供SchemaRDD,如果您选择多个列,那么您仍然需要使用序数,但您始终可以一次选择一列.例:

// setup and some data
val sqlContext = new org.apache.spark.sql.SQLContext(sc)
import sqlContext._
case class Score(name: String, value: Int)
val scores = 
  sc.textFile("data.txt").map(_.split(",")).map(s => Score(s(0),s(1).trim.toInt))
scores.registerAsTable("scores")

// initial query
val original = 
  sqlContext.sql("Select value AS myVal, name FROM scores WHERE name = 'foo'")

// now a simple "language-integrated" query -- no registration required 
val secondary = original.select('myVal)
secondary.collect().foreach(println)

现在辅助是一个只有一列的SchemaRDD,尽管原始查询中有别名,它仍可正常工作.

编辑:但请注意,您可以注册生成的SchemaRDD并使用直接SQL语法进行查询,而无需其他案例类.

original.registerAsTable("original")
val secondary = sqlContext.sql("select myVal from original")
secondary.collect().foreach(println)

第二次编辑:一次处理一行RDD时,可以使用匹配的语法按名称访问列:

val secondary = original.map {case Row(myVal: Int, _) => myVal}

虽然如果’=>’的右侧可能会变得很麻烦需要访问许多列,因为它们需要在左侧匹配. (这来自source code for the Row companion object中非常有用的评论)

点赞