Go構造体のMongoDB更新を実装しようとしています。GoでのmongoDBの更新の仕組みを理解していません
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)
}
}
これは、値が更新されなかったことを示す、エラーメッセージを生成:必需品まで剥奪、それは次のようになります。私は何が欠けていますか?
私は、1つのフィールドを更新することは可能ですが、コードがMongoDBを知らないデータレイヤーにあるとすれば、一般的な方法で実装するのは難しいでしょう。私。 Goオブジェクトを更新し、バッキングストアのオブジェクトのコピーを更新する必要があります。私は、オブジェクトを取得し、手動で "差分"を行うことができ、 "$ set"ドキュメントを構築することができると思いますが、更新を行うたびに検索を追加するのは非常に効率的です。
編集:
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)
}
}
とまだ同じ結果()を受信しています:。は "_id" でマップをしようと、私は次のようにコードを修正しようとした
を削除UpdateId()の呼び出しはエラーを返さないことに注意してください。
あなたはこの文を使用して '_id'フィールド' col.Update(obj1.Id、bson.M { "$セット":&OBJ1})を更新しようとしているでは不可能です ' MongoDBなので、エラーです。 '$ set'式で使用する' _id'フィールドを持たないオブジェクトを作成する必要があります。 – chridam
私は構造体でそれを行う方法を見ていません。私が来ることができる最も近いのは、BSONにマーシャリングしてからマップにアンマーシャリングし、マップから "_id"エントリを削除することです。これを行うより良い方法はありますか? –