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.
I think using the inline
field tag is the best option for you. The mgo/v2/bson documentation states:
inline Inline the field, which must be a struct or a map,
causing all of its fields or keys to be processed as if
they were part of the outer struct. For maps, keys must
not conflict with the bson keys of other struct fields.
Your struct should then be defined as follows:
type Cube struct {
Square `bson:",inline"`
Depth int
}
Edit
inline
also exists in mgo/v1/bson
incase you are using that one.