用mgo存储嵌套结构 [英] Storing nested structs with 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 thejson.Marshal()
function first and pass the bytes tocollection.Upsert()
, it is stored as binary, which I don't want, but if I usecollection.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 inmgo/v1/bson
incase you are using that one.这篇关于用mgo存储嵌套结构的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!