sql >> Base de Datos >  >> NoSQL >> MongoDB

Personalice la operación de actualización de mgo

Para responder a la "Mi verdadera pregunta:¿Cómo puedo personalizar el comportamiento de mgo antes de la inserción? ":puede personalizar la ordenación de bson definiendo bson Getter al modelo

Para ilustrar cómo funciona, simplifiquemos el modelo para evitar documentos anidados:

type Game struct {
    ID int `bson:"_id"`
    Name string
    Stats [] float64
}

Con newGame de la siguiente manera:

newGame := Game{
    ID: 1,
    Name: "foo",
    Stats: []{5.0}
}

La actualización col.UpsertId(newGame.ID, newGame) por defecto marshals newGame en JSON, produciendo una consulta mongo como:

update({_id:1}, {name: "foo", stats: [5]}, {upsert: true});

Para hacer uso de $set , $push etc., puede definir un captador de bson personalizado. Por ejemplo

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
}

Entonces la actualización col.UpsertId(newGame.ID, newGame) producirá una consulta mongodb

update({_id:1}, {$set: {name: "foo"}, $push: {stats: {$each: [5]}}}, {upsert: true});

Para que quede muy claro:el serializador personalizado se usará en todas las consultas de mgo, por lo que probablemente no desee definirlo directamente en el modelo, sino en su derivado para usar solo en operaciones 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})