猿问

Golang官方MongoDB驱动ObjectID怪异行为

我正在尝试在 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,期望数据库将用它的值填充它。相反,它使用全零,因此第二个等插入失败


multiple write errors: [{write errors: [{E11000 duplicate key error collection: collection.name index: _id_ dup key: { : ObjectId('000000000000000000000000') }}]}, {<nil>}]

如果我使用 a*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()结构上的函数吗?


慕容708150
浏览 142回答 2
2回答

翻翻过去那场雪

我是否使用 omitempty 指令都没关系,结果相同。omitempty标记ID应该可以工作。例如:type User struct {&nbsp; &nbsp; ID&nbsp; &nbsp; &nbsp;primitive.ObjectID `json:"id" bson:"_id,omitempty"`&nbsp; &nbsp; Name&nbsp; &nbsp;string&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;`json:"name" bson:"name"`&nbsp; &nbsp; Email&nbsp; string&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;`json:"email" bson:"email"`}collection.InsertOne(context.Background(), User{Name:"Foo", Email:"Baz"})如果您不指定omitepmty标记,那么您观察到的行为只是Go 结构行为;因此,如果省略任何结构字段,它将为零值。在这种情况下,因为您已将字段类型指定为original.ObjectID,ObjectId('000000000000000000000000')所以是零值。这就是为什么您需要在插入之前先生成一个值的原因,即:collection.InsertOne(context.Background(),&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;User{ ID: primitive.NewObjectID(),&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Name: "Foo",&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Email: "Bar"})有没有办法让数据库处理 ID?从技术上讲,如果在发送到服务器之前未提供ObjectId,MongoDB 驱动程序会自动生成它。您可以尝试在插入时使用bson.M而不是 struct 以省略该_id字段,即collection.InsertOne(context.Background(),&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;bson.M{"name":"Foo", "email":"Bar"})上面的代码片段是使用mongo-go-driver v1.3.x 编写的

慕的地6264312

omitemptystruct 标签应该可以工作:type User struct {&nbsp; &nbsp; ID&nbsp; &nbsp; &nbsp;primitive.ObjectID `json:"id" bson:"_id,omitempty"`&nbsp; &nbsp; Name&nbsp; &nbsp;string&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;`json:"name" bson:"name"`&nbsp; &nbsp; Email&nbsp; string&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;`json:"email" bson:"email"`}该primitive.ObjectID类型实现了bsoncodec.Zeroer接口,因此如果它是空对象 ID(全为 0),则应从文档中省略它,并且驱动程序将为您生成一个新的。你可以试试这个并发布输出吗?
随时随地看视频慕课网APP

相关分类

Go
我要回答