比较使用reduceByKey的日期

时间:2016-05-04 11:45:14

标签: scala apache-spark scala-collections

在scala中我看到reduceByKey((x: Int , y Int) => x + y),但我想将一个值迭代为字符串并进行一些比较。我们是否可以reduceByKey使用reduceByKey(x: String , y: String)

代码:

val sparkConf = new SparkConf().setMaster("local").setAppName("Spark AVRO Read")
val sc = new SparkContext(sparkConf) 
val inPath= "/home/053764/episodes.avro" 
val sqlContext = new SQLContext(sc) 
val df = sqlContext.read.avro(inPath) 

val rows: RDD[Row] = df.rdd 
val doc = df.select("doctor").rdd.map(r => r(0) val docsss = rows.map(r => (r(2), r(1))) 

val reduce = docsss.reduceByKey((first, second) => { 
val firstDate = LocalDateTime.parse(first) 
val secondDate = LocalDateTime.parse(second) 
if (firstDate.isBefore(secondDate)) first else second 
})

请告诉我如何使用按键减少

将值重复为字符串

2 个答案:

答案 0 :(得分:1)

Spark中的

PairRDDFunctions.reduceByKey适用于RDD[(K, V)]形式的任何RDD。 reduceByKey将采用类型K(可以使用等式检查进行正确比较),并为任何类型(V, V) => V调用函数V

这是一个(Int,String)元组的简短示例,其中减少了两个字符串:

val sc = new SparkContext(conf)
val rdd = sc.parallelize(Seq((1, "01/01/2014"), (1, "02/01/2014")))
rdd.reduceByKey((first, second) => {
  val firstDate = LocalDateTime.parse(first)
  val secondDate = LocalDateTime.parse(second)

  if (firstDate.isBefore(secondDate)) first else second
})

编辑:

正如@TheArchetypalPaul正确指出的那样,由于日期是年/零填充月/零填充日的常量格式,您可以利用lexicographical order并比较两个String值而不是将它们解析为DateTime个对象。这基本上减少了代码:

val sc = new SparkContext(conf)
val rdd = sc.parallelize(Seq((1, "01/01/2014"), (1, "02/01/2014")))
rdd.reduceByKey((first, second) => if (first > second) first else second)

请注意,这确实限制了您使用的特定格式。如果情况发生变化,您最好使用为日期创建LocalDateTime对象的第一个版本。

答案 1 :(得分:0)

当我尝试将Docsss的类型声明为字符串时,我没有声明任何类型:

 val docsss : String = rows.map(r => (r(2),r(1)))

它的说法

  type mismatch; found : org.apache.spark.rdd.RDD[(Any, Any)]
                 required: String    val rows: RDD[Row] = df.rdd