2

mgo/txn には Upsert がないため、ドキュメントが既に存在するかどうかわからない場合は、Insert に続いて Update を実行しています。このように (これは単純な例であることに注意してください。実際には、別のドキュメントも変更します) --

ops := []txn.Op{{
    C:      "test",
    Id:     t.Id,
    Insert: t,
}, {
    C:      "test",
    Id:     t.Id,
    Update: bson.M{"$set": bson.M{"num": 123}},
}}

これはうまくいきます。残念ながら、どのフィールドが変更されたかを正確に知る必要があります。私は通常、オブジェクトを受け取って一連の関連ドキュメントを保存する Save() 関数内でこれを実行するため、通常、どのフィールドが変更されたかわかりません。代わりにこのようなことをしてみました -

ops := []txn.Op{{
    C:      "test",
    Id:     t.Id,
    Insert: t,
}, {
    C:      "test",
    Id:     t.Id,
    Update:t,
}}

しかし、「修飾子と非修飾子を混在させることはできません」というエラーが表示されるため、うまくいかないようです。私が思いついた唯一の解決策は、個々のフィールドごとに「$set」することでした-

ops := []txn.Op{{
    C:      "test",
    Id:     t.Id,
    Insert: t,
}, {
    C:      "test",
    Id:     t.Id,
    Update: bson.M{"$set": bson.M{"num": 123}},
}, {
    C:      "test",
    Id:     t.Id,
    Update: bson.M{"$set": bson.M{"other": 234}},
}}

しかし、これは...不格好です。何か不足していますか?ドキュメント全体を更新する方法はありますか?

4

1 に答える 1

2

すべてのコンテンツをもう一度再送信することを考えると、少し疑わしいように見えますが、値自体を に提供することで、値のすべてのフィールドを設定できます$set

    {
        C:      "test",
        Id:     t.Id,
        Update: bson.M{"$set": t},
    }

また、値を手動で送信することを選択した場合でも、複数の操作で値を送信する理由はないことに注意してください。これはうまくいくでしょう:

    {
        C:      "test",
        Id:     t.Id,
        Update: bson.M{"$set": bson.M{"foo": 1, "bar": 2}},
    }

最後に、トランザクション機械でドキュメントを使用すると、機械自体に必要な追加フィールドが取得されることに注意してください。ドキュメント全体をカスタム コンテンツで置き換えると、これらのフィールドがなくなり、txn パッケージが適切に動作しなくなります。

于 2014-06-27T18:06:58.130 に答える