Odpověď na „Moje skutečná otázka:Jak mohu přizpůsobit chování mgo před upsertem? " - řazení bson si můžete přizpůsobit definováním bson Getter k modelu.
Abychom ilustrovali, jak to funguje, zjednodušíme model, abychom se vyhnuli vnořeným dokumentům:
type Game struct {
ID int `bson:"_id"`
Name string
Stats [] float64
}
S newGame následovně:
newGame := Game{
ID: 1,
Name: "foo",
Stats: []{5.0}
}
Aktualizace col.UpsertId(newGame.ID, newGame)
ve výchozím nastavení maršálové newGame
do JSON, produkující mongo dotaz jako:
update({_id:1}, {name: "foo", stats: [5]}, {upsert: true});
Chcete-li použít $set
, $push
atd., můžete definovat vlastní getter bson. Např.
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
}
Takže aktualizace col.UpsertId(newGame.ID, newGame)
vytvoří dotaz mongodb
update({_id:1}, {$set: {name: "foo"}, $push: {stats: {$each: [5]}}}, {upsert: true});
Aby to bylo křišťálově jasné – vlastní marshaler se bude používat ve všech dotazech mgo, takže jej pravděpodobně nebudete chtít definovat přímo na model, ale na jeho odvozeninu, která se použije pouze v operacích upsert:
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})