【问题标题】:Incorrect ModifiedCount and MatchedCount using mongodb/mongo-go-driver and Azure CosmosDB使用 mongodb/mongo-go-driver 和 Azure CosmosDB 的 ModifiedCount 和 MatchedCount 不正确
【发布时间】:2020-05-01 15:58:45
【问题描述】:

我正在尝试使用连接到 Azure CosmosDB 实例 (v3.6) 的 mongodb/mongo-go-driver (v1.2.1) 编写一个简单的 CRUD 测试应用程序。考虑以下代码摘录。

Client 结构中剥离 Update 函数,为简洁起见省略

func (c *Client) Update(ctx context.Context, filter, update bson.M) error {    
    res, err := c.collection.UpdateOne(ctx, filter, update, options.Update())
    if err != nil {
        return Error{ErrFunctional, "failed to update document", err}
    }

    if res.MatchedCount != 1 {
        return Error{
            Code: ErrNotFound,
            msg:  "document not found",
        }
    }

    if res.ModifiedCount != 1 {
        return Error{
            Code: ErrNotUpdated,
            msg:  "document not updated",
        }
    }

    return nil
}

Runner 代码如下所示

type doc struct {
    count int
}

id, err := dbClient.Insert(context.TODO(), doc{1})
if err != nil {
    panic(fmt.Errorf("insert failed: %v", err))
}

err = dbClient.Update(context.TODO(), bson.M{"_id": id}, bson.M{"$set": bson.M{"count": 2}})
if err != nil {
    panic(fmt.Errorf("update failed: %v", err))
}

err = dbClient.Delete(context.TODO(), bson.M{"_id": id})
if err != nil {
    panic(fmt.Errorf("delete failed: %v", err))
}

正如您在代码中看到的,我正在尝试完成以下步骤:

  1. 插入记录{"count": 1}(此操作正常,文档已插入)
  2. 将插入记录更新为{"count": 2}(因未找到文档错误而失败)
  3. 删除记录(代码永远不会到达这里)

程序在第二步失败。我检查了驱动程序返回的结果,MatchedCountModifiedCount 始终为 0。但是数据库 已更新为正确的数据。很奇怪,对吧?现在有趣的是,如果我使用 MongoDB shell(CLI,使用 brew 安装)执行相同的步骤,那么这些步骤将毫无问题地完成。

我已经尝试了过滤器和更新语句的所有变体以使其正常工作,但无济于事。我有一种感觉,它与 Golang 驱动程序有关。我有什么遗漏或做错了吗?请随时询问更多信息,我很乐意编辑问题以提供它。

【问题讨论】:

  • 请注意,CosmosDB 是 Microsoft 制作的模拟 MongoDB,因此它与 MongoDB go 驱动程序并非 100% 兼容。尝试在真实的 MongoDB 服务器中使用相同的代码,看看是否仍然失败。
  • 我没有提到这段代码确实适用于真正的 MongoDB 服务器。我知道 CosmosDB MongoDB API 只是一个模拟,但它应该与官方驱动程序兼容:/
  • @jfarleyx by "library" 你的意思是 Go 驱动程序?如果相同的代码适用于真正的 MongoDB 服务器,则错误在 CosmosDB 中,而不是相反。 upsert:true 也是 never 任何官方 MongoDB 驱动程序默认设置的,因为它的含义非常糟糕。
  • @jfarleyx 如果您尝试针对真正的 MongoDB 服务器测试您的代码并且它做正确的事情,那么您肯定会知道错误在于 CosmosDB :)
  • @kevinadi 无视我的评论,我已将其删除。我使用 collection.replaceone 方法确实遇到了与 OP 相同的问题,但我误读了有关 upsert: true 的文档。正如你提到的,这不是原因。也许这是 CosmosDB 的一些问题。

标签: mongodb azure go azure-cosmosdb azure-cosmosdb-mongoapi


【解决方案1】:

原来这只是连接字符串中的一个愚蠢错误。出于某种原因,我使用了这种格式。

mongodb://<username>:<password>@<app>.documents.azure.com:10255/?ssl=true&replicaSet=globaldb&maxIdleTimeMS=120000&retrywrites=false"

更改为这种格式,现在一切正常。

mongodb://<username>:<password>@<app>.mongo.cosmos.azure:10255/?ssl=true&replicaSet=globaldb&maxIdleTimeMS=120000&retrywrites=false"

SMH。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-03-12
    • 2021-01-29
    • 2022-12-20
    • 2020-03-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多