用mgo存储嵌套结构 [英] Storing nested structs with mgo

查看:148
本文介绍了用mgo存储嵌套结构的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图从嵌套严格的go结构构建mongo文档,并且遇到了从go结构到mongo对象的转换问题。我已经在这里建立了 非常简化的版本: http://play.golang.org/p/yPZW88deOa

 包主

导入(
os
fmt
encoding / json


类型Square结构{
长度int
宽度int
}

类型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} 
{长度:2,宽度:3, :4}

这是完全有道理的。看起来Write函数或json.Marshal函数有一些崩溃嵌套结构的功能,但是当我尝试使用mgo函数 func(* Collection )Upsert http://godoc.org/labix .ORG / V2 /氧化镁#Collection.Upsert )。如果我先使用 json.Marshal()函数并将字节传递给 collection.Upsert(),那么以二进制形式存储,这是我不想要的,但是如果我使用 collection.Upsert(bson.M(_ id:id,& c)嵌套结构:

  {
Square:{
Length:2
宽度:3
}
深度:4
}

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

  {
长度:2,
宽度:3,
深度:4
}

是否有一些我很想念的标志可以轻松处理我现在唯一可以看到的替代方法是通过去除嵌套的结构来严格减少代码的可读性,而我真的很讨厌这样做。再一次,我的实际代码比这个例子复杂得多,所以如果我可以通过保持嵌套来避免更复杂化,那肯定会更可取。

我认为使用 code> inline 字段标记是您的最佳选择。 mgo / v2 / bson文档声明:

inline内联该字段必须是结构或映射,
会导致其所有字段或键的处理过程与if
它们是外部结构的一部分。对于地图,键必须
不与其他结构字段的bson键冲突。

您的结构应该如下定义:

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



/ code>也存在于 mgo / v1 / bson 中,因此您正在使用那个。


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.

这篇关于用mgo存储嵌套结构的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆