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更直观、更简单。因此,我的问题是:

  • 我应该避免BSON导入吗
  • 我可以在不使用BSON或指定整个接口的情况下查询所有匹配模式吗
  • 我应该像在
    JSON:“name”
    中那样同时指定JSON和BSON键吗 它们可以互换吗
  • 我应该避免BSON导入吗
  • 我看没有理由这样做。MongoDB(通过
    mgo
    )和BSON携手同行。无论您是否导入
    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
    您希望如何表示您的数据,并且应该使用simple
    bson.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驱动程序时,它就派上了用场。也许它应该有一个自己的帖子,来了解更多关于使用它们的包类型的优点