亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

Golang官方MongoDB驅動ObjectID怪異行為

Golang官方MongoDB驅動ObjectID怪異行為

Go
慕容708150 2022-05-18 09:32:40
我正在嘗試在 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()結構上的函數嗎?
查看完整描述

2 回答

?
翻翻過去那場雪

TA貢獻2065條經驗 獲得超14個贊

我是否使用 omitempty 指令都沒關系,結果相同。


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 結構行為;因此,如果省略任何結構字段,它將為零值。在這種情況下,因為您已將字段類型指定為original.ObjectID,ObjectId('000000000000000000000000')所以是零值。


這就是為什么您需要在插入之前先生成一個值的原因,即:


collection.InsertOne(context.Background(), 

                     User{ ID: primitive.NewObjectID(), 

                           Name: "Foo", 

                           Email: "Bar"})

有沒有辦法讓數據庫處理 ID?


從技術上講,如果在發送到服務器之前未提供ObjectId,MongoDB 驅動程序會自動生成它。


您可以嘗試在插入時使用bson.M而不是 struct 以省略該_id字段,即


collection.InsertOne(context.Background(), 

                     bson.M{"name":"Foo", "email":"Bar"})

上面的代碼片段是使用mongo-go-driver v1.3.x 編寫的


查看完整回答
反對 回復 2022-05-18
?
慕的地6264312

TA貢獻1817條經驗 獲得超6個贊

omitemptystruct 標簽應該可以工作:


type User struct {

    ID     primitive.ObjectID `json:"id" bson:"_id,omitempty"`

    Name   string             `json:"name" bson:"name"`

    Email  string             `json:"email" bson:"email"`

}

該primitive.ObjectID類型實現了bsoncodec.Zeroer接口,因此如果它是空對象 ID(全為 0),則應從文檔中省略它,并且驅動程序將為您生成一個新的。你可以試試這個并發布輸出嗎?


查看完整回答
反對 回復 2022-05-18
  • 2 回答
  • 0 關注
  • 131 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號