mongodb之Golang官方MongoDB驱动程序ObjectID怪异行为
emanlee
阅读:55
2025-06-02 22:19:02
评论:0
我正在尝试在golang中使用官方的mongodb驱动程序,并且看到了意外情况。
如果我有一个像
type User struct {
ID primitive.ObjectID `json:"id" bson:"_id"`
Name string `json:"name" bson:"name"`
Email string `json:"email" bson:"email"`
}
我使用
Name和
Email创建了一个新的实例,但是省略了ID,期望DB将其值填充其中。相反,它使用全零,因此第二个以此类推的插入失败,并带有
multiple write errors: [{write errors: [{E11000 duplicate key error collection: collection.name index: _id_ dup key: { : ObjectId('000000000000000000000000') }}]}, {<nil>}]
如果我使用
*primitive.ObjectID,我只会在
null而不是零上得到同一类错误
multiple write errors: [{write errors: [{E11000 duplicate key error collection: collection.name index: _id_ dup key: { : null }}]}, {<nil>}]
是否使用
omitempty指令都没关系,结果相同。
如果我完全省略
ID字段,那么它可以工作,但是我的结构上没有该数据。
有没有办法让数据库处理ID?还是必须在结构上显式调用
NewObjectID()函数?
请您参考如下方法:
It doesn't matter if I use the omitempty directive or not, same result.
omitempty上的
ID标记应该可以正常工作。例如:
type User struct {
ID primitive.ObjectID `json:"id" bson:"_id,omitempty"`
Name string `json:"name" bson:"name"`
Email string `json:"email" bson:"email"`
}
collection.InsertOne(context.Background(), User{Name:"Foo", Email:"Baz"})
如果您未指定
omitepmty标记,那么您观察到的行为仅仅是
Go structs行为;因此,如果省略任何struct字段,它将为零值。在这种情况下,由于您将字段类型指定为
primitive.ObjectID,因此
ObjectId('000000000000000000000000')为零值。
这就是为什么您需要在插入之前首先生成一个值的原因,即:
collection.InsertOne(context.Background(),
User{ ID: primitive.NewObjectID(),
Name: "Foo",
Email: "Bar"})
Is there a way to have the DB handle the ID?
从技术上讲,如果未将 ObjectId发送给服务器,则它是MongoDB驱动程序自动生成的。
您可以在插入时尝试使用 bson.M而不是结构,以忽略
_id字段,即
collection.InsertOne(context.Background(),
bson.M{"name":"Foo", "email":"Bar"})
上面的代码段是使用 mongo-go-driver v1.3.x编写的
声明
1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,请转载时务必注明文章作者和来源,不尊重原创的行为我们将追究责任;3.作者投稿可能会经我们编辑修改或补充。



