使用 Golang mongo-driver 的 MongoDB 自动增量 ID

Posted

技术标签:

【中文标题】使用 Golang mongo-driver 的 MongoDB 自动增量 ID【英文标题】:MongoDB Auto Increment ID with Golang mongo-driver 【发布时间】:2020-07-19 13:51:56 【问题描述】:

基于documentation,go.mongodb.org/mongo-driver 在插入未提供 ID 的文档时似乎没有提供自动增加 ID 的方法。

    type Document struct 
        ID             int    `bson:"_id"`
        Foo            string `bson:"foo"`
    

    document := &DocumentFoo: "test"

    filter := bson.M"_id": bson.M"$eq": document.ID
    update := bson.M"$set": document

    res, err := mongoClient.Database(dbName).
        Collection(collectionName).
        UpdateOne(ctx, filter, update,
            options.Update().SetUpsert(true))

在上面的代码示例中,ID 将默认为 int 的零值,即0,并将在 MongoDB 中持久化为"_id":0,"foo":"test"

当没有使用mongo-driver 提供 ID 时,是否有一种自动递增 ID 的干净方法,而无需自己执行跟踪最后一个 ID 的逻辑?假设数据库中已经有 5 个文档,那么在没有提供 ID 的情况下运行上面的代码将持久化"_id":6,"foo":"test"

【问题讨论】:

如果您不依赖于值本身的增量,请使用 UUID 来实现唯一性。它在 go 中很常见。 自动递增的 ID 实际上对于向后兼容非常重要,但如果不自己实现很多逻辑,就无法使用 go.mongodb.org/mongo-driver 找到好的解决方案。 您是否有不想使用默认 ObjectID 的原因? 【参考方案1】:

我发现了同样的问题,我认为的解决方案是定义没有ID的Document结构:

type Document struct 
    Foo string `bson:"foo"`

然后,如果使用 mongo-driver 执行 InsertOne 操作:

res, err := mongoClient.Database(dbName).Collection(collectionName).InsertOne(ctx, document)

_id会自动在数据库中创建(您可以重复InsertOne操作多次,新的_id会出现)。

mongodb 文档解释了这种行为:“如果文档没有指定 _id 字段,那么 mongod 将添加 _id 字段并在插入之前为文档分配一个唯一的 ObjectId。”(您可以在https://docs.mongodb.com/manual/reference/method/db.collection.insertOne/#db.collection.insertOne中阅读更多详细信息)

如果你因为某种原因需要新创建的_id,你可以使用下面的sn-p作为参考来检索它:

fmt.Println("New Document created with mongodb _id: " + res.InsertedID.(primitive.ObjectID).Hex())

primitive.ObjectID与此相关:import "go.mongodb.org/mongo-driver/bson/primitive")

希望这会有所帮助!

【讨论】:

【参考方案2】:

您还可以执行以下操作:

    type Document struct 
        ID             int    `bson:"_id,omitempty"`
        Foo            string `bson:"foo"`
    

【讨论】:

以上是关于使用 Golang mongo-driver 的 MongoDB 自动增量 ID的主要内容,如果未能解决你的问题,请参考以下文章

golang操作mongodb

Golang操作MongoDB DAO - 增删改查

golang:* mongo.Database没有字段或方法CreateCollection

golang time json mongodb 时间处理

哪个库更高效“gopkg.in/mgo.v2”或“go.mongodb.org/mongo-driver/mongo”[关闭]

golang mongodb 驱动二次封装