“文档” 菜单
文档首页
/ / /
Go 驱动程序
/

使用 BSON

在此页面上

  • 概述
  • 数据类型
  • 结构体标记
  • BSON 选项
  • 解组

在本指南中,你可以了解 Go 驱动程序如何处理 BSON 和 Go 类型之间的转换。将 GO 类型转换为 BSON 的过程称为编组,反之称为解组

以下部分解释 Go 驱动程序如何表示 BSON 数据 以及您如何调整默认编组和解组行为。

MongoDB 以称为 BSON的二进制表示形式存储文档,可以轻松灵活地进行数据处理。

Go 驱动程序提供了四类主要驱动程序来处理 BSON 数据:

  • D:BSON 文档的有序表示(切片)

  • M:BSON 文档的无序表示(映射)

  • A:BSON 数组的有序表示形式

  • E:D 类型内部的单个元素

以下示例演示如何使用 bson.D 类型构造查询筛选器,匹配其中 quantity 字段值大于 100 的文档:

filter := bson.D{{"quantity", bson.D{{"$gt", 100}}}}

如需进一步了解 Go 驱动程序如何处理 BSON 数据,请参阅 bson 程序包 API 文档

在 Go 中,结构体是具有声明数据类型的数据字段的集合。您可以使用结构体标记修改结构体字段的默认编组和解组行为,结构体标记是附加到结构体字段的可选元数据片段。结构体标记最常见的用途是指定 BSON 文档中与结构体字段对应的字段名称。下表给出可以在 Go 驱动程序中使用的其他结构体标记:

结构标记
说明
omitempty
如果字段设置为与字段类型对应的零值,则不会对字段编组。
minsize
如果该字段的类型为 int64uintuint32uint64,并且该字段的值适合采用有符号 int32 来表示,则该字段将被序列化为 BSON int32 而不是BSON int64。如果字段值不适合采用有符号 int32 来表示,则忽略此标签。
truncate
如果字段类型是非浮点数字类型, 则解组到该字段中的 BSON 双精度数将在小数点处截断。
inline
如果字段类型是结构或映射字段,则字段在编组时将扁平化, 而在解组时将取消扁平化。

如果您不指定结构体标记,则 Go 驱动程序将使用以下规则编组结构体:

  1. 驱动程序仅编组和解组已导出的字段。

  2. 驱动程序使用相应结构体字段的小写字母生成 BSON 密钥。

  3. 此驱动程序会将嵌入的结构字段封送为子文档。每个键 均为该字段的小写类型表示法。

  4. 如果指针不为 nil,则驱动程序会将指针字段作为底层类型。 如果指针为 nil,则驱动程序将其编组为 BSON null 值。

  5. 解组时,Go 驱动程序会针对 interface{} 类型的字段遵循这些 D/M 类型映射。驱动程序将 BSON 文档解组为 D 类型,解组到 interface{} 字段中。

可以指定 BSON 选项来调整 Client 实例的编组和解组行为。要在 Client 上设置 BSON 选项,请创建并配置 BSONOptions 实例。

此示例将执行以下动作:

  • 通过配置以下设置来创建 BSONOptions 实例:

    • UseJSONStructTags字段设置为true,这指示驱动程序在未指定"bson"结构标记的情况下使用"json"结构标记

    • NilSliceAsEmpty 字段设置为 true,指示驱动程序将 nil Go 切片编组为空 BSON 数组

  • BSONOptions 实例传递给 SetBSONOptions() 辅助方法,以指定 ClientOptions 实例

  • 创建 Client 以应用指定的 BSON 封送和拆收行为

bsonOpts := &options.BSONOptions {
UseJSONStructTags: true,
NilSliceAsEmpty: true,
}
clientOpts := options.Client().
ApplyURI("<connection string>").
SetBSONOptions(bsonOpts)
client, err := mongo.Connect(context.TODO(), clientOpts)

提示

如要进一步了解 BSONOptions 类型,请参阅 BSONOptions API 文档。有关指定 BSONOptions 实例并使用这些选项来创建客户端的示例,请参阅 Connect() BSONOptions 示例

您可以对 FindOne 方法或任何 *mongo.Cursor 实例的结果运用 Decode() 方法来解组 BSON 文档。

Decode() 方法返回 error 类型,其中包含以下值之一:

  • nil 如果文档与查询相匹配,并且检索和解组该文档时没有出错。

  • 如果驱动程序检索了您的文档但无法取消封送结果,Decode() 方法将返回取消封送错误。

  • 如果在执行 FindOne() 方法期间检索文档出错,该错误将传播到 Decode() 方法,并且 Decode() 方法会返回该错误。

用于 FindOne() 方法返回的 SingleResult 类型时,如果没有文档与查询筛选器匹配,Decode() 也可能会返回 ErrNoDocuments 错误。

以下示例演示了如何使用 Decode() 方法解组并读取简单 FindOne() 操作的结果:

coll := client.Database("db").Collection("students")
filter := bson.D{{"age", 8}}
var result bson.D
err := coll.FindOne(context.TODO(), filter).Decode(&result)
fmt.Println(result)

此外,Cursor 类型还会使用 All() 方法,而此方法会将游标中存储的所有文档同时拆收到数组中。

bson 包包括一系列 Marshal()Unmarshal() 方法,这些方法可处理 []byte 类型的 BSON 编码数据。

以下代码演示如何使用 bson 包中的方法将 BSON 解组回用户定义的结构体:

type Item struct {
Category string
Quantity int32
}
doc, err := bson.Marshal(bson.D{{"category", "plate"}, {"quantity", 6}})
var test Item
err = bson.Unmarshal(doc, &test)
fmt.Printf("Unmarshalled Struct:\n%+v\n", test)

注意

您可以使用 Raw 类型从 BSON 文档字节切片中检索元素,而无需将其解组为 Go 类型。此类型允许您查找单个元素,而无需解组整个 BSON 文档。

要详细了解用于Cursor 类型的编组和解组方法,请参阅 Cursor API 文档

要详细了解bson 包中的编组和解组方法,请参阅 bson API 文档

← 企业身份验证机制