Overview
In this guide, you can learn how to use the Go driver to configure read and write operations.
Read and Write Settings
You can control how the driver routes read operations by setting a read preference. You can also control how the driver handles data consistency and durability by setting a read concern or write concern. Read concerns specify the level of durability required for the data when performing read operations, and write concerns specify how the driver waits for acknowledgement of write operations in a replica set.
You can set write concern, read concern, and read preference options at the following levels:
Client level, which sets the default for all operation executions unless overridden
Session level
Transaction level
Database level
Collection level
The preceding list also indicates the increasing order of precedence of the option settings. For example, if you set a read concern for a transaction, it will override a read concern set for the client.
Write Concern
A write concern describes the number of data-bearing members in a replica set that must acknowledge a write operation, such as an insert or update, before the operation returns as successful. By default, the write operation is successful if only the primary replica set member acknowledges it.
Options
The MongoDB Go Driver provides the writeconcern
package, which lets you
specify the write concern for a replica set. Set the write concern by passing an
instance of the WriteConcern
type to the SetWriteConcern()
method. The
WriteConcern
type provides the following methods to select common write
concern specifications:
Method | Description |
---|---|
| The client requests acknowledgement that write operations propagate to
tagged members of a mongod instance. For more
information, see the Write Concern specification.Parameter: tag (string) |
| The client requests acknowledgement that the replica set has
written the changes to the on-disk journal. For more information, see the
Write Concern specification. Parameter: none |
| The client requests acknowledgement that write operations propagate to the
majority of data-bearing voting members. For more information, see the
Write Concern specification. Parameter: none |
| The client requests requests no acknowledgment of write
operations. For more information, see the
Write Concern specification for w: 0. Parameter: none |
| The client requests acknowledgement that the replica set has
written the changes to memory on one node, such as the standalone mongod or
the primary in a replica set. For more
information, see the Write Concern specification for w: 1. Parameter: none |
Tip
Write Concern Timeout
You cannot set a timeout on a WriteConcern
instance. Instead, set
the timeout at the operation level by using the WithTimeout()
method when creating a Context. To learn more, see
Single Timeout Setting in the Connection Options guide.
If you require a more specialized write concern, you can define a custom
WriteConcern
struct literal. You can set the following fields in a
WriteConcern
struct:
Field | Description |
---|---|
| Specifies the number of mongod instances or tagged members
that write operations must propagate to for acknowledgement. Common values include
1 , 0 , and "majority" .Type: string or int |
| Specifies whether the replica set must write the changes to the on-disk
journal for acknowledgement. Type: bool |
Tip
Alternatively, you can specify a write concern in your connection string. See the Server manual entry on Write Concern Options for more information.
Example
The following code shows how you can specify different write concerns
at the client and collection level. The client-level write concern
requests acknowledgement from two replica set members and sets journaling to
false
. The collection-level write concern requests
acknowledgement from the majority of replica set members.
uri := "mongodb://<hostname>:<port>" journal := false cliWC := &writeconcern.WriteConcern{ W: 2, Journal: &journal, } clOpts := options.Client().ApplyURI(uri).SetWriteConcern(cliWC) client, err := mongo.Connect(clOpts) ... collWC := writeconcern.Majority() collOpts := options.Collection().SetWriteConcern(collWC) coll := client.Database("db").Collection("myColl", collOpts)
Read Concern
The read concern option allows you to determine which data the client returns from a query. The default read concern level is "local", meaning that the client returns the instance’s most recent data, with no guarantee that the data has been written to a majority of the replica set members.
Options
The MongoDB Go Driver provides the readconcern
package, which lets you specify
the read concern for a replica set. Set the read concern by passing an instance
of a ReadConcern
type to the SetReadConcern()
method. The
ReadConcern
type has the following methods to specify the read concern:
Method | Description |
---|---|
| The query returns data from the instance with no guarantee that the data has been written to a majority of the replica set members. For more information, see the Read Concern specification. |
| The query returns data that reflects all
successful writes issued with a write concern of |
| The query returns the instance’s most recent data. For more information, see the Read Concern specification. |
| The query returns the instance’s most recent data acknowledged as having been written to a majority of members in the replica set. For more information, see the Read Concern specification. |
| The query returns a complete copy of the
data in a |
Example
The following code shows how you can specify a read concern of
"majority". The code then selects a Collection
with this option.
rc := readconcern.Majority() opts := options.Collection().SetReadConcern(rc) database := client.Database("db") coll := database.Collection("myCollection", opts)
Read Preference
The read preference option specifies how the MongoDB client routes read operations to the members of a replica set. By default, an application directs its read operations to the primary member in a replica set.
Read preference consists of the read preference mode and, optionally, a tag set list, the maxStalenessSeconds option, and the hedged read option.
Options
The MongoDB Go Driver provides the readpref
package, which lets you specify
the read preference for a replica set. Set the read preference by passing an
instance of the ReadPref
type to the SetReadPreference()
method. The
ReadPref
type has the following methods to specify the read preference:
Method | Description |
---|---|
| The client reads from a random eligible replica set member, based on a specified latency threshold. For more information, see the Read Preference Server manual entry. |
| The client reads from the current replica set primary node. For more information, see the Read Preference Server manual entry. |
| The client reads from the primary node if it's available. If the primary is unavailable, operations read from secondary members. For more information, see the Read Preference Server manual entry. |
| The client reads from the secondary members of the replica set. For more information, see the Read Preference Server manual entry. |
| The client reads from the secondary nodes if one or more is available. If the secondaries are unavailable, operations read from the primary member. For more information, see the Read Preference Server manual entry. |
Tip
Alternatively, you can specify a read preference in your connection string. See the Server manual entry on Read Preference Options for more information.
Example
The following code shows how you can specify a read preference to read
from secondary nodes. The code then selects a Database
with this option.
rp := readpref.Secondary() opts := options.Database().SetReadPreference(rp) database := client.Database("db", opts)
Retryable Reads and Writes
The Go driver automatically retries certain read and write operations a single time if they fail due to a network or server error.
You can explicitly disable retryable reads or retryable writes by setting the
RetryReads
or RetryWrites
option to False
when creating a new client
by using the options.Client
struct.
The following example disables retryable reads and writes for a client by using
the ClientOptions
setter functions:
// Defines the client options clientOps := options.Client(). ApplyURI(uri). SetRetryWrites(false). SetRetryReads(false) // Creates a new client using the specified options client, err := mongo.Connect(clientOps) if err != nil { panic(err) }
To learn more about supported retryable read operations, see Retryable Reads in the MongoDB Server manual. To learn more about supported retryable write operations, see Retryable Writes in the MongoDB Server manual.
Collation
You can specify a collation to modify the behavior of read and write operations. A collation is a set of language-specific rules for string comparison, such as for letter case and accent marks.
By default, MongoDB sorts strings using binary collation. This default collation uses the ASCII standard character values to compare and order strings. Languages and locales have specific character-ordering conventions that differ from the ASCII standard, and you can choose to apply a different set of collation rules to your operation.
You can specify a collation at the following levels:
Collection: Sets the default collation for operations on the collection. You cannot define a collation for an existing collection.
Index: Sets the collation for operations that use the index.
Operation: Sets the operation's collation and overrides any inherited collations.
Specify a Collation
To specify a collation, create a Collation
object. You must define the Locale
field
of the Collation
object, but all other fields are optional. For example, the following code
example specifies a Collation
object with the "en_US"
locale collation:
myCollation := &options.Collation{Locale: "en_US"}
For a complete list of Collation
object fields, visit the Collation API documentation. To see all the supported locales and the
default values for the Locale
fields, visit Supported Languages and Locales.
Set a Collation on a Collection or View
You can apply a collation when you create a new collection or view. This defines the default
collation for any operations called on that collection or view. Set a collation through a
CreateCollectionOptions
or CreateViewOptions
object. Then, call the
CreateCollection()
or CreateView()
method with your options object as an argument.
Create a Collection Example
The following example creates a new collection called books
and specifies a default
collation with the "fr"
locale. The Strength
collation field has a value of 1
to ignore differences in letter accents.
myCollation := &options.Collation{Locale: "fr", Strength: 1} opts := options.CreateCollection().SetCollation(myCollation) err := db.CreateCollection(context.TODO(), "books", opts) if err != nil { panic(err) }
Use the Default Collation Example
If you call an operation that uses a collation on the books
collection, the operation
uses the default collation specified in the Create a Collection Example.
Assume the books
collection contains the following documents:
{"name" : "Emma", "length" : "474"} {"name" : "Les Misérables", "length": "1462"} {"name" : "Infinite Jest", "length" : "1104"} {"name" : "Cryptonomicon", "length" : "918"} {"name" : "Ça", "length" : "1138"}
Note
To learn how to insert documents, see Insert a Document.
The following example uses the Find()
method to return all documents with a name
value
that alphabetically precedes "Infinite Jest"
:
filter := bson.D{{"name", bson.D{{"$lt", "Infinite Jest"}}}} cursor, err := coll.Find(context.TODO(), filter) if err != nil { panic(err) } var results []bson.D if err = cursor.All(context.TODO(), &results); err != nil { panic(err) } for _, result := range results { res, _ := bson.MarshalExtJSON(result, false, false) fmt.Println(string(res)) }
{"name":"Emma","length":"474"} {"name":"Cryptonomicon","length":"918"} {"name":"Ça","length":"1138"}
If the code doesn't specify a default books
collation, the Find()
method
follows default binary collation rules to determine the name
values
that precede "Infinite Jest"
. These rules place words beginning with "Ç"
after those beginning with "I". The output resembles the following:
{"name":"Emma","length":"474"} {"name":"Cryptonomicon","length":"918"}
To learn more about the Find()
method, see Find Documents.
Set a Collation on an Index
You can apply a collation when you create a new index on a collection. The index stores an ordered representation of the documents in the collection, so your MongoDB instance doesn't perform the ordering for sorting operations in-memory.
To use the index in an operation, your operation must use the same collation as the one
specified in the index. Additionally, ensure that the operation is covered by the index that
contains the collation. Set a collation through an IndexOptions
object and pass this object
as an argument to the CreateOne()
method.
Example
After creating the books
collection and applying a default collation, as shown in the
Create a Collection Example section, you cannot change the collection's default collation.
However, you can create an index for the collection with a different collation.
The following example uses the CreateOne()
method to create an ascending index on the
name
field and specifies a new collation with an "en_US"
locale:
myCollation := &options.Collation{Locale: "en_US"} opts := options.Index().SetCollation(myCollation) indexModel := mongo.IndexModel{ Keys: bson.D{{"name", 1}}, Options: opts, } name, err := coll.Indexes().CreateOne(context.TODO(), indexModel) if err != nil { panic(err) } fmt.Println("Name of Index Created: " + name)
Name of Index Created: name_1
Set a Collation on an Operation
Operations that read, update, and delete documents from a collection can use collations. Applying a collation to an operation overrides any default collation previously defined for a collection.
If you apply a new collation to an operation that differs from an index's collation, you cannot use that index. As a result, the operation may not perform as well as one that is covered by an index. For more information on the disadvantages of sorting operations not covered by an index, see Using Indexes to Sort Query Results. See the MongoDB manual for a list of operations that support collation.
Example
You can use operations that support collation to update and query documents in the
books
collection.
The following example uses the Find()
method to return documents in which the length
value is greater than "1000"
. The NumericOrdering
collation field has a value of
true
to ensure that values are sorted in numerical order rather than alphabetical
order:
filter := bson.D{{"length", bson.D{{"$gt", "1000"}}}} myCollation := &options.Collation{Locale: "en_US", NumericOrdering: true} opts := options.Find().SetCollation(myCollation) cursor, err := coll.Find(context.TODO(), filter, opts) if err != nil { panic(err) } var results []bson.D if err = cursor.All(context.TODO(), &results); err != nil { panic(err) } for _, result := range results { res, _ := bson.MarshalExtJSON(result, false, false) fmt.Println(string(res)) }
{"name":"Les Misérables","length":"1462"} {"name":"Infinite Jest","length":"1104"} {"name":"Ça","length":"1138"}
If the code doesn't specify a collation with a NumericOrdering
field set to
true
, the same Find()
operation compares length
values as
strings. In this case, the output resembles the following:
{"name":"Emma","length":"474"} {"name":"Les Misérables","length":"1462"} {""name":"Infinite Jest","length":"1104"} {"name":"Cryptonomicon","length":"918"} {"name":"Ça","length":"1138"}
Additional Information
To learn more about the Find()
method, see the Find Documents guide.
To learn more about the concepts discussed in this guide, visit the following manual pages:
API Documentation
To learn more about the methods discussed in this guide, see the following API Documentation: