You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

定义ID为uint64 `bson:"_id"`时,如何让MongoDB自动生成ID?

这是Go操作MongoDB时很容易碰到的小问题,我来给你分享几种靠谱的解决办法:

方法一:改用MongoDB原生的ObjectID类型

MongoDB默认的_id字段类型是ObjectID,咱们把结构体里的ID字段换成primitive.ObjectID类型,它的默认值是primitive.NilObjectID,当插入时驱动会识别这个空值,自动让MongoDB生成新的ObjectID。

修改后的结构体代码:

import "go.mongodb.org/mongo-driver/bson/primitive"

type User struct {
    ID       primitive.ObjectID `json:"id" bson:"_id"`
    UserName string             `json:"user_name" bson:"userName"`
    Email    string             `json:"email" bson:"email"`
}

创建实例时完全不用管ID字段:

u := User{
    UserName: "me",
    Email:    "me@mail.com",
}

这样插入后,MongoDB就会自动生成标准的ObjectID作为_id,这也是最贴合MongoDB设计的方案,推荐优先用这个。

方法二:把ID字段改成指针类型(保留uint64)

如果你的业务逻辑必须用uint64类型的ID,可以把ID字段声明为*uint64,它的默认值是nil而不是0。当插入时,MongoDB看到_id是nil,就会自动生成ObjectID(注意此时生成的_id是ObjectID类型,后续查询时需要处理类型转换)。

修改后的结构体:

type User struct {
    ID       *uint64 `json:"id" bson:"_id"`
    UserName string  `json:"user_name" bson:"userName"`
    Email    string  `json:"email" bson:"email"`
}

创建实例同样无需赋值ID:

u := User{
    UserName: "me",
    Email:    "me@mail.com",
}

这个方案适合不想改类型但又要自动生成_id的场景,唯一要注意的就是后续查询时_id的类型转换问题。

方法三:手动生成自增uint64 ID

如果业务需要uint64类型的自增ID,那可以自己实现一个自增序列逻辑,比如用MongoDB的findAndModify来获取下一个自增ID,再赋值给ID字段:

// 示例:获取自增ID的函数(实际需要结合MongoDB实现)
func getNextSequence(seqName string) uint64 {
    // 这里省略具体的findAndModify逻辑,核心是原子性地递增序列值
    // 返回递增后的uint64值
}

// 创建实例时手动赋值ID
nextID := getNextSequence("user_id")
u := User{
    ID:       nextID,
    UserName: "me",
    Email:    "me@mail.com",
}
r, err := collection.InsertOne(context.TODO(), u)

这个方案需要额外维护自增序列,适合有特定ID格式要求的场景,但相对前两种要麻烦一些。


内容的提问来源于stack exchange,提问作者Fotiadis M.

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.08 11:57:34