Я пытаюсь реализовать обновление MongoDB для структуры Go. В упрощенном виде это выглядит примерно так:
type MyStruct struct {
Id bson.ObjectId `bson:"_id"`
Fruit string `bson:"fruit"`
}
func TestUpdate(t *testing.T) {
obj1 := MyStruct{Id: bson.NewObjectId(),Fruit: "apple"}
var obj2 MyStruct
session, _ := mgo.Dial("whatever")
col := session.DB("test").C("collection")
col.Insert(&obj1)
obj1.Fruit = "cherry"
if err := col.Update(obj1.Id, bson.M{"$set": &obj1}); err != nil {
t.Errorf(err.Error())
}
if err := col.Find(bson.M{"Id": obj1.Id}).One(&obj2); err != nil {
t.Errorf(err.Error())
}
if obj1.Fruit != obj2.Fruit {
t.Errorf("Expected %s, got %s", obj1.Fruit, obj2.Fruit)
}
}
Это генерирует сообщение об ошибке, указывающее, что значение не было обновлено. Что мне не хватает?
Я понимаю, что возможно просто обновить одно поле, но, учитывая, что оно находится на уровне данных, выше которого код не имеет никаких знаний о MongoDB, это было бы сложно реализовать в общем виде. т.е. Мне действительно нужно внести какие-либо обновления в объект Go, а затем обновить копию объекта в резервном хранилище. Я полагаю, что я мог бы получить объект и выполнить «diff» вручную, создав документ «$set», но это не похоже на то, что добавление поиска каждый раз, когда я делаю обновление, было бы очень эффективным.
Изменить: попытка карты с удаленным "_id"
Я попытался изменить код на следующее:
package testmgo
import (
mgo "gopkg.in/mgo.v2"
"gopkg.in/mgo.v2/bson"
"github.com/fatih/structs"
"testing"
)
type MyStruct struct {
Id bson.ObjectId `bson:"_id"`
Fruit string `bson:"fruit"`
}
func TestUpdate(t *testing.T) {
obj1 := MyStruct{Id: bson.NewObjectId(),Fruit: "apple"}
var obj2 MyStruct
session, _ := mgo.Dial("localhost")
col := session.DB("test").C("collection")
col.Insert(&obj1)
obj1.Fruit = "cherry"
omap := structs.Map(&obj1)
delete(omap, "_id")
if err := col.UpdateId(obj1.Id, bson.M{"$set": bson.M(omap)}); err != nil {
t.Errorf(err.Error())
}
if err := col.Find(bson.M{"Id": obj1.Id}).One(&obj2); err != nil {
t.Errorf(err.Error())
}
if obj1.Fruit != obj2.Fruit {
t.Errorf("Expected %s, got %s", obj1.Fruit, obj2.Fruit)
}
}
и я все еще получаю те же результаты (Expected cherry, got apple
). Обратите внимание, что вызов UpdateId() не возвращает ошибку.
_id
с помощью этой инструкцииcol.Update(obj1.Id, bson.M{"$set": &obj1})
, что невозможно в MongoDB, отсюда и ошибка. Вам нужно создать объект, который не имеет поля_id
для использования в вашем выражении$set
. - person chridam   schedule 06.05.2016