0

Mgo and golang question.

I run into problem again. I try to update record in the database, but running simple command visitors.UpdateId(v.Id, bson.M{"$set": zscore}); where zscore is a variable of type Zscore, does not work. However if I manually convert zscore to bson.M structure, everything works fine.

Does anybody know how to update the record in mongodb using mgo, without manually dumping structure values into bson.M?

Example:

type Zscore struct {
    a float64 `bson:"a,omitempty" json:"a"`
    b float64 `bson:"b,omitempty" json:"b"`
    c float64 `bson:"c,omitempty" json:"c"`
}

v := Visitor{}
zscore := Zscore{}

visitors := updater.C("visitors")

for result.Next(&v) {
    zscore.a = 1
    zscore.b = 2
    zscore.c = 0

    //does not work
    if err := visitors.UpdateId(v.Id, bson.M{"$set": zscore}); err != nil    {
            log.Printf("Got error while updating visitor: %v\n", err)
    }

    //works
    set := bson.M{
        "zscore.a": zscore.a,
        "zscore.b": zscore.b,
        "zscore.c": zscore.c,
    }

    if err := visitors.UpdateId(v.Id, bson.M{"$set": set}); err != nil {
        log.Printf("Got error while updating visitor: %v\n", err)
    }
}
Luke
  • 61
  • 6

1 Answers1

1

All Go marshaling packages I'm aware of, including the bson package, will not marshal fields that are private (start with a lowercase letter). To fix the issue, just export the relevant fields by uppercasing the first letter of their name.

Also note that, besides the issue mentioned above, the first part of your example will not marshal in an equivalent way to the second part. bson.M{"$set": zscore} is equivalent to bson.M{"$set": bson.M{"a": ... etc ...}}.

Gustavo Niemeyer
  • 22,007
  • 5
  • 57
  • 46
  • thx, works great now... how did you know that fields cannot be private? – Luke Mar 09 '15 at 18:58
  • @Lukasz, probably from the [documentation](https://godoc.org/gopkg.in/mgo.v2/bson#Marshal): "In the case of struct values, only exported fields will be serialized." As alwyas, RTFM. – Dave C Mar 09 '15 at 22:00
  • Well... sentence "The lowercased field name is used as the key for each exported field, but this behavior may be changed using the respective field tag. " makes documentation not 100% obvious . You would think that tag controls what is serialized and what is not. – Luke Mar 10 '15 at 15:28
  • These two sentences are additive and not in conflict. Only exported fields will be serialized, and those serialized may have the _key for each exported field_ changed via the tag. – Gustavo Niemeyer Mar 12 '15 at 00:12