Spark scala使用spark-mongo连接器进行upsert

时间:2017-08-04 11:40:35

标签: mongodb scala apache-spark

有没有办法根据数据帧中的某个字段使用spark-mongo连接器来支持Mongo Collection?

4 个答案:

答案 0 :(得分:1)

截至MongoDB Connector for Spark版本1.1+(目前版本为2.2) 当您执行save()时,如下所示:

dataFrameWriter.write.mongo()
dataFrameWriter.write.format("com.mongodb.spark.sql").save()

如果数据框包含_id字段,则数据将为upserted。这意味着将更新具有相同_id值的任何现有文档,并且将插入集合中不存在_id值的新文档。

有关详细信息和摘要,另请参阅MongoDB Spark SQL

答案 1 :(得分:1)

尝试选项replaceDocument

df.select("_id").withColumn("aaa", lit("ha"))
  .write
  .option("collection", collectionName)
  .option("replaceDocument", "false")
  .mode(SaveMode.Append)
  .format("mongo")
  .save()

我不知道为什么在mongo文档中找不到此选项的任何文档

答案 2 :(得分:1)

要基于唯一键约束替换文档,请使用replaceDocument和shardKey选项。默认的shardKey是{_id:1}。 https://docs.mongodb.com/spark-connector/master/configuration/

df.write.format('com.mongodb.spark.sql') \
  .option('collection', 'target_collection') \
  .option('replaceDocument', 'true') \
  .option('shardKey', '{"date": 1, "name": 1, "resource": 1}') \
  .mode('append') \
  .save()

replaceDocument = false选项使您的文档基于shardKey进行合并。

https://github.com/mongodb/mongo-spark/blob/master/src/main/scala/com/mongodb/spark/MongoSpark.scala#L150-L182

答案 3 :(得分:0)

通过对mongo-spark's source的深入研究,这是一个简单的技巧,可以将某些字段的upsert功能添加到MongoSpark.save方法中:

// add additional keys parameter
def save[D](dataset: Dataset[D], writeConfig: WriteConfig, keys: List[String]): Unit = {
    val mongoConnector = MongoConnector(writeConfig.asOptions)
    val dataSet = dataset.toDF()
    val mapper = rowToDocumentMapper(dataSet.schema)
    val documentRdd: RDD[BsonDocument] = dataSet.rdd.map(row => mapper(row))
    val fieldNames = dataset.schema.fieldNames.toList
    val queryKeyList = keys.isEmpty match {
      case true => keys
      case false => BsonDocument.parse(writeConfig.shardKey.getOrElse("{_id: 1}")).keySet().asScala.toList
    }
    // the rest remains the same
    // ...
}