Storing nested structs with mgo

Viewed 8650

I'm trying to build a mongo document from a go struct that is heavily nested, and I'm running into a problem with the transition from go struct to a mongo object. I've built a very simplified version of what I'm trying to work with here: http://play.golang.org/p/yPZW88deOa

package main

import (
    "os"
    "fmt"
    "encoding/json"
)

type Square struct {
    Length int 
    Width int
}

type Cube struct {
    Square
    Depth int
}

func main() {
    c := new(Cube)
    c.Length = 2
    c.Width = 3
    c.Depth = 4

    b, err := json.Marshal(c)
    if err != nil {
        panic(err)
    }

    fmt.Println(c)
    os.Stdout.Write(b)
}

Running this produces the following output:

&{{2 3} 4}
{"Length":2,"Width":3,"Depth":4}

Which makes complete sense. It seems either the Write function or the json.Marshal function has some functionality that collapses the nested struct, but my problem comes when I try to insert this data into a mongo database using the mgo function func (*Collection) Upsert (http://godoc.org/labix.org/v2/mgo#Collection.Upsert). If I use the json.Marshal() function first and pass the bytes to collection.Upsert(), it is stored as binary, which I don't want, but if I use collection.Upsert(bson.M("_id": id, &c) it appears as a nested struct with the form:

{
    "Square": {
        "Length": 2
        "Width": 3
    }
    "Depth": 4
}

But what I want to do is upsert to mongo with the same structure as I get when I use the os.Stdout.Write() function:

{
     "Length":2,
     "Width":3,
     "Depth":4
}

Is there some flag I'm missing that would easily handle this? The only alternative I can see at this point is severely cutting down on the readability of the code by removing the nesting of the structs, which I really hate to do. Again, my actual code is way more complex than this example, so if I can avoid complicating it even more by keeping things nested, that would definitely be preferable.

1 Answers
Related