2016-05-06 16 views
0

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()の呼び出しはエラーを返さないことに注意してください。

+0

あなたはこの文を使用して '_id'フィールド' col.Update(obj1.Id、bson.M { "$セット":&OBJ1})を更新しようとしているでは不可能です ' MongoDBなので、エラーです。 '$ set'式で使用する' _id'フィールドを持たないオブジェクトを作成する必要があります。 – chridam

+0

私は構造体でそれを行う方法を見ていません。私が来ることができる最も近いのは、BSONにマーシャリングしてからマップにアンマーシャリングし、マップから "_id"エントリを削除することです。これを行うより良い方法はありますか? –

答えて

0

問題は、誤ったフィールドをキーとして使用していたことでした。私は "id"を "_id"にマッピングしましたが、MongoDBに名前ではなくGo属性名を使用してレコードを検索するよう依頼していました。これは正しく動作:

package testmgo 

import (
    mgo "gopkg.in/mgo.v2" 
    "gopkg.in/mgo.v2/bson" 
    "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" 

    if err := col.UpdateId(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) 
    } 
} 
関連する問題