使用mgo存储嵌套结构

时间:2013-12-30 23:58:23

标签: mongodb go mgo

我正在尝试从大量嵌套的go结构构建一个mongo文档,并且我遇到了从go struct到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)
}

运行它会产生以下输出:

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

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

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

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

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

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

1 个答案:

答案 0 :(得分:34)

我认为使用inline字段标记是您的最佳选择。 mgo/v2/bson documentation州:

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.

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

type Cube struct {
    Square `bson:",inline"`
    Depth  int
}

修改

inline也存在于mgo/v1/bson,如果你正在使用那个。