Docs 菜单
Docs 主页
/ / /
Go

FAQ

在此页面上

  • 为什么连接 MongoDB 时会出错?
  • Go 驱动程序中的连接池化是如何工作的?
  • 如何修复“WriteNull 只能在定位于元素或值上时写入,但却定位在 TopLevel 上”错误?
  • 如何将 BSON 文档转换为 JSON?

本页包含常见问题及其相应解答。

提示

如果在此页面上找不到问题的回答,请参阅问题和帮助页面,了解后续步骤和更多资源。

如果在连接到 MongoDB 部署时出现问题,请参阅连接故障排除指南,了解潜在的解决方案。

对于 MongoDB 拓扑结构中的每个服务器,每个 Client实例都有一个内置连接池。 连接池按需打开套接字以支持并发 MongoDB 操作或 goroutine ,在您的应用程序中。

每个连接池的最大大小由 maxPoolSize 选项设置,默认值为 100。如果某个服务器的在用连接数达到 maxPoolSize 值,则对该服务器的下一个请求将等待,直到出现可用连接。

Client实例为 MongoDB 拓扑结构中的每台服务器打开两个额外的套接字,用于监视服务器状态。

例如,连接到3节点副本集的客户端会打开6监控套接字。 它还根据需要打开任意数量的套接字,以支持应用程序在每台服务器上的并发操作,最多可达maxPoolSize的值。 如果maxPoolSize100且应用程序仅使用主节点(默认),则只有主节点连接池会增长,总连接数最多可为106 。 如果应用程序使用读取偏好来查询从节点,则其池也会增长,总连接数可能为306

此外,连接池受速率限制,因此每个连接池在任何时候最多只能并行创建 maxConnecting 个连接的值。在以下情况下,任何额外的 goroutine 都会停止等待:

  • 其中一个现有的 goroutines 完成创建连接,或者一个现有的连接被退回到池中。

  • 由于对创建连接的速率有限制,驱动程序重用现有连接的能力得到了提高。

您可以使用 minPoolSize 选项设置每个服务器的最小并发连接数量,此值默认为 0。设置 minPoolSize 后,连接池将以此套接字数量进行初始化。如果由于任何网络错误导致套接字关闭,导致套接字总数(包括使用中的和闲置的)下降到最小值以下,则会打开更多套接字,直至达到最小值。

您可以使用maxIdleTimeMS选项设置连接在被删除和替换之前在池中保持空闲状态的最大毫秒数,该选项默认为None (无限制)。

以下 Client 的默认配置适用于大多数应用程序:

client := mongo.Connect("<connection string>")

为每个进程创建一个客户端,并在所有操作中重复使用。为每个请求创建一个新客户端是个常见的错误,效率非常低。

如要在一个进程中支持大量并发 MongoDB 操作,您可以增加 maxPoolSize。一旦池达到其最大大小,其他操作就会等待套接字变得可用。

该驱动程序不限制可以等待套接字变为可用状态的操作数量,应用程序有责任在负载峰值期间将其池的大小限制为绑定队列。除非定义了 waitQueueTimeoutMS 选项,否则操作可以等待任何时间长度。

如果操作等待套接字的时间超过 waitQueueTimeoutMS 所定义的时长,则会引发连接错误。如果在负载峰值期间限制操作的持续时间比完成每个操作更重要,请使用此选项。

Client.Disconnect() 被任何 goroutine 调用时,驱动程序会关闭所有闲置套接字,并关闭所有正在使用的套接字,因为这些套接字会返回到池中。

bson.Marshal()方法需要一个可解码为 BSON 文档的参数,例如bson.D类型。 当您将 BSON 文档以外的内容传递给bson.Marshal()时,会出现此错误。

当您将 null 传递给 bson.Marshal() 时会发生 WriteNull 错误。可能会发生类似错误的情况包括:

  • 将字符串传递给 bson.Marshal(),引起 WriteString 错误。

  • 将布尔值传递给 bson.Marshal() 引发了 WriteBoolean 错误。

  • 将整数传递给 bson.Marshal() ,会引起 WriteInt32 错误。

当您执行内部使用bson.Marshal()方法的 CRUD 操作或直接调用bson.Marshal()对数据进行编码时,可能会遇到此错误。

以下代码会产生 WriteNull 错误,因为驱动程序无法在 FindOneAndUpdate() 操作期间将 sortOrdernull 值编码为 BSON:

var sortOrder bson.D
opts := options.FindOneAndUpdate().SetSort(sortOrder)
updateDocument := bson.D{{"$inc", bson.D{{"counter", 1}}}}
result := coll.FindOneAndUpdate(context.TODO(), bson.D{}, updateDocument, opts)
if err := result.Err(); err != nil {
panic(err)
}

下方代码演示如何正确地将 sortOrder 变量初始化为 bson.D 类型,以便驱动程序可以将其转换为 BSON:

sortOrder := bson.D{}

驾驶员提供了多种可用于将BSON文档转换为JSON的编组器方法,例如MarshalExtJSON()方法。 要查看可读形式的JSON编码,必须使用解组器方法或string类型转换来解析JSON字节格式。

以下代码使用 MarshalExtJSON() 方法将 BSON 文档转换为 JSON,然后使用 string type-casting 解析并打印 JSON 字节数组:

bsonDocument := bson.D{{"hello", "world"}}
jsonBytes, err := bson.MarshalExtJSON(bsonDocument, true, false)
if err != nil {
panic(err)
}
fmt.Println(string(jsonBytes))

要了解有关 BSON 和 Go 类型之间转换的更多信息,请参阅使用 BSON 指南

后退

使用地理空间数据