Go中的MongoDB与JSON和BSON的关系
我正在学习如何使用社区维护的Go中的MongoDB与JSON和BSON的关系,mongodb,go,struct,mongodb-query,mgo,Mongodb,Go,Struct,Mongodb Query,Mgo,我正在学习如何使用社区维护的mgorepo链接 通过这一点,我发现查询某些数据片段的方法似乎是通过BSON完成的(BSON库的社区维护版本是链接的): 这将给我所有的Person,名字是Alice 我还发现我不需要BSON来执行此查询查找()采用任何接口: c.Find(Person{ Name: "Alice", Phone: "1234", }).All(&result) 也将起作用,但仅返回指定的精确查询。如果我省略结构的一部分,如下所示: c.Find(Pers
mgo
repo链接
通过这一点,我发现查询某些数据片段的方法似乎是通过BSON完成的(BSON库的社区维护版本是链接的):
这将给我所有的Person
,名字是Alice
我还发现我不需要BSON来执行此查询<代码>查找()采用任何接口:
c.Find(Person{
Name: "Alice",
Phone: "1234",
}).All(&result)
也将起作用,但仅返回指定的精确查询。如果我省略结构的一部分,如下所示:
c.Find(Person{
Name: "Alice",
}).All(&result)
type Person struct {
Name string `bson:"name,omitempty"`
Phone string `bson:"phone,omitempty"`
}
err = c.Find(Person{
Name: "Alice",
}).All(&result)
c.Find(struct { Name string }{Name: "Alice"}).All(&result)
结果
将为空
在我看来,避免BSON更直观、更简单。因此,我的问题是:
JSON:“name”
中那样同时指定JSON和BSON键吗
它们可以互换吗mgo
)和BSON携手同行。无论您是否导入bson
,bson
仍将在后台使用(用于序列化/表示来回发送的数据)
“bson”
标记时使用ommitempty
选项,您可以这样做:
c.Find(Person{
Name: "Alice",
}).All(&result)
type Person struct {
Name string `bson:"name,omitempty"`
Phone string `bson:"phone,omitempty"`
}
err = c.Find(Person{
Name: "Alice",
}).All(&result)
c.Find(struct { Name string }{Name: "Alice"}).All(&result)
现在,如果您执行如下查询:
c.Find(Person{
Name: "Alice",
}).All(&result)
type Person struct {
Name string `bson:"name,omitempty"`
Phone string `bson:"phone,omitempty"`
}
err = c.Find(Person{
Name: "Alice",
}).All(&result)
c.Find(struct { Name string }{Name: "Alice"}).All(&result)
然后,当筛选器值被编组到BSON中时,它将只包含一个的“name”
字段,因为Phone
是它的零值,所以它不会被编组
当然,在执行插入/更新时,使用省略empty
可能不是您想要的,因此使用单一类型来表示和查询人员可能是不够的。通常,您应该“标记”Person
您希望如何表示您的数据,并且应该使用simplebson.M
值进行查询,或者创建另一个为您希望查询的方式建模的结构
JSON:“name”
中那样指定JSON和BSON键,还是可以互换json
标记,则bson
包不会使用(忽略)这些标记,同样,如果只指定bson
标记,则标准库的encoding/json
包不会使用这些标记。它们是2个不同的标签,用于2个不同的目的,由2个不同的库(包)使用
您可以指定也可以不指定两者。如果您从未打算将数据序列化为JSON,则不必指定
JSON
标记。mgo/bson包用于编码和解码所有数据库命令和结果,即使应用程序不直接使用该包
复合文本Person{Name:“Alice”}
返回一个Person
值,其中Phone
字段设置为”
。BSON编码器将该值编码为逻辑上的值{“Name”:“Alice”,“Phone”:“}
。具有此值的查询将返回名称为“Alice”且电话为“”的所有文档。显然,集合中没有与此查询匹配的文档
查询文档必须有一个名称字段,仅用于查询名称等于“Alice”的所有文档以及带有任何值或根本未设置的电话
我应该避免BSON导入吗
不,如果bson软件包有用,请直接使用它
我可以在不使用BSON或指定整个接口的情况下查询所有匹配模式吗
bson.M
类型通常是构造查询的最佳方式,但您可以不用它。例如,您可以查询名称为“Alice”的所有文档,如下所示:
c.Find(Person{
Name: "Alice",
}).All(&result)
type Person struct {
Name string `bson:"name,omitempty"`
Phone string `bson:"phone,omitempty"`
}
err = c.Find(Person{
Name: "Alice",
}).All(&result)
c.Find(struct { Name string }{Name: "Alice"}).All(&result)
您也可以使用map[string]接口{}
:
c.Find(map[string]interface{}{"Name": "Alice"}).All(&result)
最后,您可以使用BSON编码器的“omitempty”功能从编码值中省略空字段。我不推荐这种方法,因为它阻止您查询字段等于“”的文档。为此方法将结构类型更改为以下类型:
type Person struct {
Name string `bson:",omitempty"`
Phone string `bson:",omitempty"`
}
我应该像在JSON中那样指定JSON和BSON键:“name”还是可以互换
它们不能互换。根据需要为BSON编码器和JSON编码器指定标记。嘿,使用BSON类型比使用自定义结构有什么优势吗?甚至映射[字符串]字符串?我一直认为这并不重要,我更喜欢使用我的域实体的结构和映射,这样我可以更容易地在实体中进行更改,而不是在repo中进行更改。@oren使用结构对数据建模很方便,因此您可以在Go代码中轻松地使用它。使用结构进行查询并不方便(有其优点和缺点),但我通常只使用
bson.M
值进行查询,因为查询可能会有很多变化,我不想为了更简单的查询而在模型中做出妥协。谢谢,非常有帮助!我通常对插入使用结构,对查询使用映射[string]接口{}。我想在应用程序回购中不知道mgo。现在,当我尝试mgo和mongodb alpha驱动程序时,它就派上了用场。也许它应该有一个自己的帖子,来了解更多关于使用它们的包类型的优点