使用scala和Spark将RDD中的每条记录转换为数组[Map]

使用scala和Spark将RDD中的每条记录转换为数组[Map],scala,apache-spark,Scala,Apache Spark,我的RDD是\n分开的记录,看起来像 Single RDD k1=v1,k2=v2,k3=v3 k1=v1,k2=v2,k3=v3 k1=v1,k2=v2,k3=v3 并希望将其转换为数组[Map[k,v]], 其中,数组中的每个元素将是一个不同的映射[k,v],对应于一个记录 根据单个RDD中的记录,数组将包含N个这样的映射 我对scala和spark都是新手。转换过程中的任何帮助都会有所帮助 object SparkApp extends Logging with App {

我的RDD是\n分开的记录,看起来像

Single RDD

k1=v1,k2=v2,k3=v3
k1=v1,k2=v2,k3=v3
k1=v1,k2=v2,k3=v3
并希望将其转换为数组[Map[k,v]],

其中,数组中的每个元素将是一个不同的映射[k,v],对应于一个记录

根据单个RDD中的记录,数组将包含N个这样的映射

我对scala和spark都是新手。转换过程中的任何帮助都会有所帮助

object SparkApp  extends Logging with App {


  override def main(args: Array[ String ]): Unit = {
    val myConfigFile = new File("../sparkconsumer/conf/spark.conf")
    val fileConfig = ConfigFactory.parseFile(myConfigFile).getConfig(GlobalConstants.CONFIG_ROOT_ELEMENT)
    val propConf = ConfigFactory.load(fileConfig)
    val topicsSet = propConf.getString(GlobalConstants.KAFKA_WHITE_LIST_TOPIC).split(",").toSet
    val kafkaParams = Map[ String, String ]("metadata.broker.list" -> propConf.getString(GlobalConstants.KAFKA_BROKERS))


    //logger.info(message = "Hello World , You are entering Spark!!!")
    val conf = new SparkConf().setMaster("local[2]").setAppName(propConf.getString(GlobalConstants.JOB_NAME))
    conf.set("HADOOP_HOME", "/usr/local/hadoop")
    conf.set("hadoop.home.dir", "/usr/local/hadoop")
    //Lookup

    // logger.info("Window of 5 Seconds Enabled")
    val ssc = new StreamingContext(conf, Seconds(5))
    ssc.checkpoint("/tmp/checkpoint")

    val apiFile = ssc.sparkContext.textFile(propConf.getString(GlobalConstants.API_FILE))
    val arrayApi = ssc.sparkContext.broadcast(apiFile.distinct().collect())

    val nonApiFile = ssc.sparkContext.textFile(propConf.getString(GlobalConstants.NON_API_FILE))
    val arrayNonApi = ssc.sparkContext.broadcast(nonApiFile.distinct().collect())


    val messages = KafkaUtils.createDirectStream[ String, String, StringDecoder, StringDecoder ](ssc, kafkaParams, topicsSet)
    writeTOHDFS2(messages)
    ssc.start()
    ssc.awaitTermination()
  }



  def writeTOHDFS2(messages: DStream[ (String, String) ]): Unit = {
    val records = messages.window(Seconds(10), Seconds(10))
    val k = records.transform( rdd => rdd.map(r =>r._2)).filter(x=> filterNullImpressions(x))

    k.foreachRDD { singleRdd =>
      if (singleRdd.count() > 0) {


        val maps =  singleRdd.map(line => line.split("\n").flatMap(x => x.split(",")).flatMap(x => x.split("=")).foreach( x => new mutable.HashMap().put(x(0),x(1))) 


        val r = scala.util.Random
        val sdf = new SimpleDateFormat("yyyy/MM/dd/HH/mm")
        maps.saveAsTextFile("hdfs://localhost:8001/user/hadoop/spark/" + sdf.format(new Date())+r.nextInt)
      }
    }

  }

}

这里有一些代码应该是非常自我解释的

val lines = "k1=v1,k2=v2,k3=v3\nk1=v1,k2=v2\nk1=v1,k2=v2,k3=v3,k4=v4"

val maps = lines.split("\n")
 .map(line => line.split(",")
 .map(kvPairString => kvPairString.split("="))
 .map(kvPairArray => (kvPairArray(0), kvPairArray(1))))
 .map(_.toMap)

// maps is of type Array[Map[String, String]]

println(maps.mkString("\n"))

//  prints:
//  Map(k1 -> v1, k2 -> v2, k3 -> v3)
//  Map(k1 -> v1, k2 -> v2)
//  Map(k1 -> v1, k2 -> v2, k3 -> v3, k4 -> v4)

建议之词-因此不是一个“为我编写代码”的平台。我明白,深入研究Scala和Spark是很困难的,但下次请尝试自己解决问题,并发布您迄今为止的尝试以及遇到的问题。

rdd中的格式是什么?是(k1,v1),(k2,v2)等吗?欢迎来到StackOverflow:)你能把你尝试过的东西包括进来吗?这会让我们更容易理解你正在努力解决的概念。这看起来很简单。你试过什么?你的RDD中有多少行-你真的想要一个
RDD[Map[…]]
?谢谢slouc,完全为我工作,没有任何变化。已经尝试了很多变化,就是:singleRdd.Map(line=>line.split(“\n”).flatMap(x=>x.split(“,”).flatMap(x=>x.split(=”).foreach(x=>new mutable.HashMap().put(x(0),x(1)))@krupavarughese是的,好吧,写你已经尝试过的东西不要感到尴尬:)它显示了良好的意愿,并将你与那些只是发布问题并等待有人编写解决方案的用户区分开来(那些人很快就会被否决)。