将scala / spark信息写入MongoDB

时间:2018-01-27 16:04:52

标签: mongodb scala apache-spark

我有一个包含

等数据的日志数据
Started by timer
...
...
Finished: SUCCESS

对于每个日志数据,需要将日志状态(此处为“已完成”)和状态(“SUCCESS”)写入MongoDB。

case class Logs(status:String,statusCode:String)

def main(args:Array[String]){

     val sc= new SparkContext("local[*]","MongoDB")
     val lines=sc.textFile("log1.txt")
     val pairs=lines.filter(value=>value.startsWith("Finished")).
     map(lines=>lines.split(": ")).
     map(lines=>(lines(0).toString(),lines(1).toString())).

    for(keyAndValue<-pairs){
      println("key: "+va._1+" has val: "+va._2)
    }

我能够正确获取值。

现在我想将它们作为关键字和值存储在MongoDB中(“完成”,“成功”),在一个特定的数据库中存储。

我创建了mongodb配置如下:

 val spark = SparkSession.builder()
.master("local")
.appName("MongoSparkConnectorIntro")
.config("spark.mongodb.input.uri", "mongodb://localhost:27017/test.test")
.config("spark.mongodb.input.readPreference.name", "secondaryPreferred")
.config("spark.mongodb.output.uri", "mongodb://127.0.0.1/test.test")
.getOrCreate()

如何使用我创建的类来存储值?

我是否缺少任何其他配置,或者需要在数据库中以不同方式放置数据。

我尝试使用下面的代码段将信息保存到Mongo中,但是,它表示'write不是RDD的成员'。

pairs.foreachRDD({ rdd =>
import spark.implicits._
val matching = rdd.map({ case (status: String, statusCode: String)
=> Logs(status, statusCode) })
matching.write.mode("append").mongo()
})

非常感谢任何帮助。

2 个答案:

答案 0 :(得分:3)

根据mongodb docs中的说明,您必须将RDD转换为BSON文档。

此外,无需创建SparkSession(来自SparkSQL)和SparkContext,因为上下文是会话的一部分。

我在你的代码之上构建了一个简单的例子。由于Logs类必须转换为Document,我省略了这一步:

import com.mongodb.spark.MongoSpark
import org.apache.spark.sql.SparkSession
import org.bson.Document

object MongoDBTest {

  def main(args: Array[String]) {

    val spark = SparkSession.builder()
      .master("local")
      .appName("MongoSparkConnectorIntro")
      .config("spark.mongodb.input.uri", "mongodb://localhost:27017/test.test")
      .config("spark.mongodb.input.readPreference.name", "secondaryPreferred")
      .config("spark.mongodb.output.uri", "mongodb://127.0.0.1/test.test")
      .getOrCreate()

    val sc = spark.sparkContext
    val lines = sc.textFile("log1.txt")
    val pairs = lines.filter(value => value.startsWith("Finished"))
       .map(lines => lines.split(": "))
       .map(line => new Document((line(0)), line(1)))
    for (va <- pairs) {
      println(va)
    }

    MongoSpark.save(pairs)
  }
}

必要的依赖

libraryDependencies += "org.apache.spark" %% "spark-sql" % "2.2.0"
libraryDependencies += "org.mongodb.scala" %% "mongo-scala-driver" % "2.2.0"
libraryDependencies += "org.mongodb.spark" %% "mongo-spark-connector" % "2.2.0"

快速检查mongodb会显示最小日志文件的结果:

>db.test.find({})
{ "_id" : ObjectId("5a70a04737331a6da0a6ef96"), "Finished" : "SUCCESS" }
{ "_id" : ObjectId("5a70a04737331a6da0a6ef97"), "Finished" : "FAILURE" }

答案 1 :(得分:0)

DataFrameWriterDataset的属性。

如果Logs是案例类,例如:

case class Logs(status: String, statusCode: String)

只需替换

val matching = rdd.map({ 
  case (status: String, statusCode: String) => Logs(status, statusCode)
})

val matching = rdd.map({ 
  case (status: String, statusCode: String) => Logs(status, statusCode)
}).toDF