「私の本当の質問:アップサートの前にmgoの動作をカスタマイズするにはどうすればよいですか? "- bson Getter を定義することで、bsonマーシャリングをカスタマイズできます。 モデルに。
それがどのように機能するかを説明するために、ネストされたドキュメントを避けるためにモデルを単純化しましょう:
type Game struct {
ID int `bson:"_id"`
Name string
Stats [] float64
}
newGameの場合:
newGame := Game{
ID: 1,
Name: "foo",
Stats: []{5.0}
}
更新col.UpsertId(newGame.ID, newGame)
デフォルトでは、newGame
をマーシャルします JSONに変換し、次のようなmongoクエリを生成します:
update({_id:1}, {name: "foo", stats: [5]}, {upsert: true});
$set
を利用するには 、$push
など、カスタムbsonゲッターを定義できます。例:
func (g Game) GetBSON() (interface{}, error) {
return bson.M{
"$set": bson.M{"name": g.Name},
"$push": bson.M{"stats": bson.M{"$each": g.Stats}},
}, nil
}
したがって、更新col.UpsertId(newGame.ID, newGame)
mongodbクエリを生成します
update({_id:1}, {$set: {name: "foo"}, $push: {stats: {$each: [5]}}}, {upsert: true});
明確にするために、カスタムマーシャラーはすべてのmgoクエリで使用されるため、モデルに直接定義するのではなく、アップサート操作でのみ使用する派生物に定義することをお勧めします。
type UpdatedGame struct {
Game
}
func (g UpdatedGame) GetBSON() (interface{}, error) {
return bson.M{....}
}
.....
newGame := Game{
ID: 1,
Name: "foo",
Stats: []{5.0}
}
col.UpsertId(newGame.ID, UpdatedGame{newGame})