【问题标题】:Duplicate key error in Mongo Sharded ClusterMongo Sharded Cluster 中的重复键错误
【发布时间】:2019-02-03 08:46:44
【问题描述】:

我在 Mongo Sharded Cluster(MSC) 中遇到了重复密钥错误,使用 Mongo 副本集时不会发生这种错误。

我在客户端应用中有简单的操作:

// pseudocode - email is unique key
subscriber = db.newsletter.find({email: "john@smith.com"})
if (subscriber == null) {
  db.newsletter.insert({email: "john@smith.com", name: "John"})
} else {
  db.newsletter.update({email: "john@smith.com"}, {name: "John"})
}

我没有将它包含在上面的代码中,但我需要检索文档的 _id,因此不能使用 upsert。

错误: 如果上述过程对同一封新电子邮件执行两次,则会导致重复密钥错误。第二次迭代将无法找到订阅者,因此它将尝试插入,尽管文档已经存在于集合中。

据我所知,运行上述客户端的单个实例不应导致重复键错误,但确实如此。

【问题讨论】:

    标签: mongodb distributed


    【解决方案1】:

    这将是 findAndModify commandfindOneAndUpdate method 的工作。

    有一个upsert 标志,如果文档不存在,它将创建该文档。您还必须使用 new 标志来返回新文档(如果已创建)。

    【讨论】:

    • 明确一点:find 没有找到任何东西,但由于进程的并发性质,插入会引发重复键错误。 Afaik upsert 不返回文档,所以如果文档已经存在,我不知道如何检索 _id
    • @xReprisal :我还没有深入了解您的孤立问题,但无论如何您都需要以某种方式将您的操作包装到某种形式的事务中。 findAndModify 是一个内置命令,它执行此操作(一次查找和更新,并且还使用 upsert 标志“如果不存在则创建”)。此外,文档特别声明它modifies and returns a single document,这是您需要的第二部分。
    • 你说得对,我没有仔细阅读你的答案。我虽然你在谈论upsert 方法而不是标志。对此感到抱歉。看起来这就是我正在寻找的解决方案。感谢您的帮助。
    猜你喜欢
    • 2013-06-11
    • 2014-07-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-12-30
    • 2022-08-15
    • 2021-06-04
    • 2021-04-27
    相关资源
    最近更新 更多