FAQ
On this page
This page contains frequently asked questions and their corresponding answers.
Tip
If you can't find an answer to your problem on this page, see the Issues & Help page for next steps and more resources.
Why Am I Getting Errors While Connecting to MongoDB?
If you have trouble connecting to a MongoDB deployment, see the Connection Troubleshooting Guide for possible solutions.
How Does Connection Pooling Work in the Go driver?
Every Client
instance has a built-in connection pool for each server
in your MongoDB topology. Connection pools open sockets on demand to support
concurrent MongoDB operations, or goroutines, in your application.
The maximum size of each connection pool is set by the maxPoolSize
option, which
defaults to 100
. If the number of in-use connections to a server reaches
the value of maxPoolSize
, the next request to that server will wait
until a connection becomes available.
The Client
instance opens two additional sockets per server in your
MongoDB topology for monitoring the server's state.
For example, a client connected to a 3-node replica set opens 6
monitoring sockets. It also opens the necessary sockets to support
an application's concurrent operations on each server, up to
the value of maxPoolSize
. If maxPoolSize
is 100
and the
application only uses the primary (the default), then only the primary
connection pool grows and there can be at most 106
total connections. If the
application uses a read preference to query the
secondary nodes, their pools also grow and there can be 306
total connections.
Additionally, connection pools are rate-limited such that each connection pool
can only create, at maximum, the value of maxConnecting
connections
in parallel at any time. Any additional goroutine stops waiting in the
following cases:
One of the existing goroutines finishes creating a connection, or an existing connection is checked back into the pool.
The driver's ability to reuse existing connections improves due to rate-limits on connection creation.
You can set the minimum number of concurrent connections to
each server by using the minPoolSize
option, which defaults to 0
.
After setting minPoolSize
, the connection pool is initialized with
this number of sockets. If sockets close due to any network errors, causing
the total number of sockets (both in use and idle) to drop below the minimum, more sockets
open until the minimum is reached.
You can set the maximum number of milliseconds that a connection can
remain idle in the pool before being removed and replaced with
the maxIdleTimeMS
option, which defaults to None
(no limit).
The following default configuration for a Client
works for most applications:
client := mongo.Connect(context.TODO(), "<connection string>")
Create a client once for each process, and reuse it for all operations. It is a common mistake to create a new client for each request, which is very inefficient.
To support high numbers of concurrent MongoDB operations
within one process, you can increase maxPoolSize
. Once the pool
reaches its maximum size, additional operations wait for sockets
to become available.
The driver does not limit the number of operations that
can wait for sockets to become available and it is the application's
responsibility to limit the size of its pool to bound queuing
during a load spike. Operations can wait for any length of time
unless you define the waitQueueTimeoutMS
option.
An operation that waits more than the length of time defined by
waitQueueTimeoutMS
for a socket raises a connection error. Use this
option if it is more important to bound the duration of operations
during a load spike than it is to complete every operation.
When Client.Disconnect()
is called by any goroutine, the driver
closes all idle sockets and closes all sockets that are in
use as they are returned to the pool.
How Can I Fix the "WriteNull can only write while positioned on a Element or Value but is positioned on a TopLevel" Error?
The bson.Marshal()
method requires a parameter that can be decoded
into a BSON document, such as the bson.D
type. This error occurs
when you pass something other than a BSON document to
bson.Marshal()
.
The WriteNull
error occurs when you pass a null
to
bson.Marshal()
. Situations in which a similar error can occur
include the following:
You pass a string to
bson.Marshal()
, causing aWriteString
error.You pass a boolean to
bson.Marshal()
, causing aWriteBoolean
error.You pass an integer to
bson.Marshal()
, causing aWriteInt32
error.
You may encounter this error when you perform a CRUD operation that
internally uses the bson.Marshal()
method or when you call
bson.Marshal()
directly to encode data.
The following code produces a WriteNull
error because the driver
cannot encode the null
value of sortOrder
to BSON during
the FindOneAndUpdate()
operation:
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) }
The following code shows how to correctly initialize the sortOrder
variable as a bson.D
type so that the driver can convert it to BSON:
sortOrder := bson.D{}
How Do I Convert a BSON Document to JSON?
The driver provides a variety of marshaler methods that can be used to
convert a BSON document to JSON, such as the MarshalExtJSON()
method. To view a readable form of the JSON encoding, you must use
an unmarshaler method or string type-casting to parse the JSON byte
format.
The following code converts a BSON document to JSON using the
MarshalExtJSON()
method, then parses and prints the JSON byte array
using string type-casting:
bsonDocument := bson.D{{"hello", "world"}} jsonBytes, err := bson.MarshalExtJSON(bsonDocument, true, false) if err != nil { panic(err) } fmt.Println(string(jsonBytes))
{"hello":"world"}
To learn more about conversions between BSON and Go types, see the Work with BSON guide.