【问题标题】:How to upsert document in MongoDB Java driver 3如何在 MongoDB Java 驱动程序 3 中插入​​文档
【发布时间】:2015-08-17 03:21:31
【问题描述】:

使用 mongodb java 驱动程序版本 3(特别是 v3.0.1)更新插入文档的惯用方法是什么?

我们有一个会话集合,当一个新的会话被创建或修改时,我们希望在一个操作中更新它 - 而不是必须查询一个文档是否存在然后插入或替换。

我们旧的 upsertion 代码使用了 scala 驱动程序 casbah 2.7.3。它看起来像:

import com.mongodb.casbah.MongoCollection
import com.mongdb.DBObject
val sessionCollection: MongoCollection = ...
val sessionKey: String = ...
val sessionDocument: DBObject = ... // Either create a new one, or find and modify an existing one

sessionCollection.update(
    "_id" -> sessionKey,
    sessionDocument
    upsert = true
)

在我们当前的项目中,我们只使用普通的 java 3.0.1 驱动程序,并且我们使用 BsonDocument 而不是 DBObject 以使其更安全。我试图用类似的东西替换上面的内容:

import com.mongodb.client.MongoCollection
val sessionCollection: MongoCollection = ...
val sessionKey: String = ...
val sessionDocument: BsonDocument = // Either create a new one, or find and modify an existing one

val updateOptions = new UpdateOptions
updateOptions.upsert(true)

sessionCollection.updateOne(
    "_id" -> new BsonString(sessionKey),
    sessionDocument,
    updateOptions
)

这会引发错误“java.lang.IllegalArgumentException: Invalid BSON field name ...”。 this question 中涵盖了该错误,但该问题中的操作并未尝试在一个操作中进行更新 - 他们使用上下文来决定是否替换/更新/插入等...

我对 scala 或 java 中的代码示例很满意。

谢谢!

【问题讨论】:

    标签: java mongodb scala mongodb-java casbah


    【解决方案1】:

    在 Mongo Java Driver 3.0 系列中,我们添加了一个新的 Crud API,它更加明确,因此对初学者友好。该计划已在多个 MongoDB 驱动程序上推出,但与旧 API 相比,它确实包含一些更改。

    由于您没有使用update operator 更新现有文档,因此updateOne 方法不合适。

    您描述的操作是replaceOne 操作,可以这样运行:

    sessionCollection.replaceOne(
        "_id" -> new BsonString(sessionKey),
        sessionDocument,
        (new UpdateOptions()).upsert(true)
    )
    

    【讨论】:

    • 感谢您的帮助。我认为尽管您的建议不是我所追求的。我想要一个操作,如果该 id 不存在则插入一个新会话,或者如果它确实存在则更新现有会话(即“更新插入”)。 replaceOne 只做后者。当我使用你的代码 sn -p 尝试在数据库中插入一个新会话时,它自然会返回 AcknowledgedUpdateResult{matchedCount=0, modifiedCount=null, upsertedId=null} 并且对数据库没有影响。
    • 确保在 updateOptions 中设置了 upserted,我已经阐明了示例。由于您不是通过更新运算符进行更新,而是进行了 upsert 替换,因此您需要 replaceOne 方法。
    • 谢谢罗斯!现在可以了。如果您的答案是 Scala 代码,您可以在 new UpdateOptions 周围加上括号吗?将其更改为(new UpdateOptions).upsert(true)。否则无法编译。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-21
    • 1970-01-01
    • 2015-05-13
    • 2014-11-05
    • 1970-01-01
    相关资源
    最近更新 更多