首页 > 解决方案 > Go 中的 MongoDB 与 JSON 和 BSON 的关系

问题描述

我正在学习如何使用此处mgo链接的社区维护的存储库。

我通过这个例子发现查询某些数据的方式似乎是通过 BSON 完成的(BSON 库的社区维护版本在此处链接):

type Person struct {
    Name      string
    Phone     string
}

c.Find(bson.M{"name": "Alice"}).All(&result)

这会给我所有Person的名字Alice

我还发现我不需要 BSON 来执行此查询。Find()采用任何接口:

c.Find(Person{
    Name: "Alice",
    Phone: "1234",
}).All(&result)

也可以,但只返回指定的确切查询。如果我像这样遗漏一部分结构:

c.Find(Person{
    Name: "Alice",
}).All(&result)

result将是空的。


在我看来,避免 BSON 更直观、更简单。所以我的问题是:

  1. 我应该避免 BSON 导入吗?
  2. 我可以在不使用 BSON 或指定整个接口的情况下查询所有匹配模式吗?
  3. 我应该像 in 一样指定 JSON 和 BSON 键json:"name"还是可以互换?

标签: mongodbgostructmongodb-querymgo

解决方案


mgo/bson 包用于对所有数据库命令和结果进行编码和解码,即使应用程序不直接使用该包。

复合文字Person{ Name: "Alice" }返回一个字段设置为的Person值。BSON 编码器将此值编码为逻辑上的值。具有此值的查询将返回名称等于“Alice”且电话等于“”的所有文档。显然,集合中没有与此查询匹配的文档。Phone""{"Name": "Alice", "Phone": ""}

查询文档必须有一个 Name 字段,仅用于查询 Name 等于“Alice”和 Phone 具有任何值或根本没有设置的所有文档。

我应该避免 BSON 导入吗?

不,有帮助时直接使用 bson 包。

我可以在不使用 BSON 或指定整个接口的情况下查询所有匹配模式吗?

类型通常是构造查询的bson.M最佳方式,但您也可以不使用它。例如,您可以像这样查询名称为“Alice”的所有文档:

c.Find(struct { Name string }{Name: "Alice"}).All(&result)

您还可以使用map[string]interface{}

c.Find(map[string]interface{}{"Name": "Alice"}).All(&result)

最后,您可以使用 BSON 编码器的“omitempty”功能从编码值中省略空字段。我不推荐这种方法,因为它会阻止您查询字段等于“”的文档。对于这种方法,将结构类型更改为以下内容:

type Person struct {
    Name  string `bson:",omitempty"`
    Phone string `bson:",omitempty"`
}

我应该像 json:"name" 那样指定 JSON 和 BSON 键,还是它们可以互换?

它们不可互换。根据需要为 BSON 编码器和 JSON 编码器指定标签。


推荐阅读