使用 mongo-go-driver,如何有效地从 WriteError 中检索重复的字段名称?

问题描述 投票:0回答:3

我的收藏中有三个唯一的索引。当用户不小心在字段

B
中插入重复的数据时,我如何知道重复项来自字段
B


在违反唯一索引约束时,mongo-go-driver 行为返回 err
WriteException
,它基本上由 WriteError 数组和一些其他对象组成。

WriteError
本身(来自 mongo-go-driver):

// WriteError is an error that occurred during the execution of a write operation. This error type is only returned as part
// of a WriteException or BulkWriteException.
type WriteError struct {
    // The index of the write-in the slice passed to an InsertMany or BulkWrite operation that caused this error.
    Index int

    Code    int
    Message string
}

在调试会话期间,我发现 WriteError 的值为:

{
    Index: 0
    Code: 11000
    Message: E11000 duplicate key error collection: auth.example index: B_1 dup key: { : "default-role-external-user" }
}

我知道我总是可以通过

Code
(11000)推断出唯一约束违规,但库没有提供单个字段来检索导致重复错误的字段名称。

我知道我总是可以解析

Message
字符串作为最后的手段,但考虑到 Golang 和 MongoDB 已经共存了很长一段时间,而且我确信我不是唯一遇到这个问题的人,我期待更强大和更有效的方法来检索导致重复错误的字段名称,我还没有找到。

mongodb go mongo-go
3个回答
1
投票

简短而令人悲伤的答案是,目前官方 mongo-go 驱动程序没有更好的方法。


0
投票

需要知道唯一字段中的值是否已被采用的应用程序通常会查询数据库以获取该值,而不是按照您的要求解析服务器返回的消息。

这种情况并不是 MongoDB 或 Go 所特有的 - 我不知道有任何 MongoDB 驱动程序可以从错误消息中解析唯一索引违规,而且我也没有听说过针对关系数据库这样做。


0
投票

正如所指出的,没有关于此错误的结构化信息,因此我们必须自己推出一些信息。请注意,解析错误消息依赖于实现细节而不是已发布的 API,这使得它有点脆弱。手头有自动化测试以确保其有效!

索引设置

我正在创建一个名为“events”的集合,并在文档中的“external_uuid”字段上配置索引。请注意,名称(“unique_external_uuid_constraint”)是明确给出的,正是为了稍后搜索它。

mongo --eval 'db.createCollection("events")'
mongo --eval 'db.events.createIndex({"external_uuid": 1}, {name: "unique_external_uuid_constraint", unique: true})'

错误处理

res, err := s.events.InsertOne(ctx, document)
if err != nil {
    // find out whether we actually have a MongoDB write error
    var write_exc mongo.WriteException
    if !errors.As(err, &write_exc) {
        return nil, err
    }

    // further dissect the write error:
    // E11000 seems to be MongoDB's "duplicate key error", a unique
    // constraint violation. We now only need to check the index
    // that prevented the insert, which we do by string matching.
    if write_exc.HasErrorCodeWithMessage(11000, "index: unique_external_uuid_constraint") {
        return nil, events.DuplicateEventUUID
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.