使用mgo存储嵌套结构

Ver*_*ran 16 go mongodb mgo

我正在尝试从一个大量嵌套的go结构构建一个mongo文档,而且我遇到了从go结构转换为mongo对象的问题.我已经构建了一个非常简化的版本,我正在尝试使用它: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)
}
Run Code Online (Sandbox Code Playgroud)

运行此命令会产生以下输出:

&{{2 3} 4}
{"Length":2,"Width":3,"Depth":4}
Run Code Online (Sandbox Code Playgroud)

这完全有道理.似乎Write函数或json.Marshal函数都有一些功能可以折叠嵌套结构,但是当我尝试使用mgo函数将这些数据插入mongo数据库时,我的问题出现了func (*Collection) Upsert(http://godoc.org/labix .org/v2/mgo#Collection.Upsert).如果我json.Marshal()首先使用该函数并将字节传递给collection.Upsert()它,它将存储为二进制文件,这是我不想要的,但如果我使用collection.Upsert(bson.M("_id": id, &c)它,它将显示为具有以下形式的嵌套结构:

{
    "Square": {
        "Length": 2
        "Width": 3
    }
    "Depth": 4
}
Run Code Online (Sandbox Code Playgroud)

但我想要做的是使用与我使用os.Stdout.Write()函数时相同的结构来插入mongo :

{
     "Length":2,
     "Width":3,
     "Depth":4
}
Run Code Online (Sandbox Code Playgroud)

是否有一些我想念的旗子很容易处理?我现在能看到的唯一选择是通过删除结构的嵌套来严重削减代码的可读性,我真的不想这样做.同样,我的实际代码比这个例子更复杂,所以如果我可以通过保持嵌套来避免使其复杂化,那肯定会更好.

ANi*_*sus 36

我认为使用inline字段标签是您的最佳选择.该氧化镁/ V2/BSON文档状态:

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.
Run Code Online (Sandbox Code Playgroud)

然后,您的结构应定义如下:

type Cube struct {
    Square `bson:",inline"`
    Depth  int
}
Run Code Online (Sandbox Code Playgroud)

编辑

inline也存在,mgo/v1/bson你正在使用那个.