Overview
In this guide, you can learn how to configure write concern, read concern, and read preference options to modify the way that the C++ driver runs read and write operations on replica sets.
Read and Write Settings Precedence
You can set write concern, read concern, and read preference options at the following levels:
Transaction
Database
Collection
This list also indicates the increasing order of precedence of the option settings. For example, if you set a read concern for a database, it will override the read concern settings inherited from the transaction.
Configure Read and Write Operations
You can control how the driver routes read operations by setting a read preference. You can also control options for how the driver waits for acknowledgment of read and write operations on a replica set by setting a read concern and a write concern.
To learn more about read and write settings and their options, see the following guides in the MongoDB Server manual:
For information on the default read and write settings, see Default MongoDB Read Concerns/Write Concerns in the MongoDB Server manual.
Transaction Configuration
Transactions run within sessions, which are groupings of related read or
write operations that you intend to run sequentially. Use the
start_session() method to obtain a session to use for the transactions.
Then, pass a mongocxx::options::transaction object to the session's
with_transaction() method. This example shows how to set the read
preference, read concern, and write concern of a transaction.
Tip
To learn more about sessions, see Server Sessions in the MongoDB Server manual.
The example configures the following settings:
k_primaryread preference: Read operations retrieve data from the primary replica set member.k_majorityread concern: Read operations return the instance's most recent data that has been written to a majority of replica set members.k_acknowledgedwrite concern: The primary replica set member must acknowledge the write operation.
auto session = client.start_session(); mongocxx::options::transaction txn_opts; { mongocxx::read_preference rp; mongocxx::read_concern rc; mongocxx::write_concern wc; rp.mode(mongocxx::read_preference::read_mode::k_primary); rc.acknowledge_level(mongocxx::read_concern::level::k_majority); wc.acknowledge_level(mongocxx::write_concern::level::k_acknowledged); txn_opts.read_preference(rp); txn_opts.read_concern(rc); txn_opts.write_concern(wc); } session.with_transaction([&](mongocxx::client_session*) { // Specify transaction operations here }, txn_opts);
Database Configuration
This example shows how to configure the following read settings for your database:
k_secondaryread preference: Read operations retrieve data from only secondary replica set members.k_majorityread concern: Read operations return the instance's most recent data that has been written to a majority of replica set members.
auto db = client["test_database"]; mongocxx::read_preference rp; mongocxx::read_concern rc; rp.mode(mongocxx::read_preference::read_mode::k_secondary); rc.acknowledge_level(mongocxx::read_concern::level::k_majority); db.read_preference(rp); db.read_concern(rc);
Collection Configuration
This example shows how to specify the following read and write concern settings for your collection:
k_localread concern: Read operations return the instance's most recent data, with no guarantee that the data has been written to a majority of replica set members.k_acknowledgedwrite concern: The primary replica set member must acknowledge the write operation.
auto coll = client["test_database"]["test_collection"]; mongocxx::read_concern rc; mongocxx::write_concern wc; rc.acknowledge_level(mongocxx::read_concern::level::k_local); wc.acknowledge_level(mongocxx::write_concern::level::k_acknowledged); coll.read_concern(rc); coll.write_concern(wc);
Tag Sets
In the MongoDB Server, you can apply key-value tags to replica-set members according to any criteria you choose. You can then use those tags to target one or more members for a read operation.
By default, the C++ driver ignores tags
when choosing a member to read from. To instruct the C++ driver
to prefer certain tags, create a mongocxx::read_preference object
and call its tags() member function. Pass your preferred tags as
an array argument to tags().
In the following code example, the tag set passed to the tags()
function instructs the C++ driver to prefer reads from the
New York data center ("dc": "ny") and to fall back to the San Francisco data
center ("dc": "sf"):
auto tag_set_ny = make_document(kvp("dc", "ny")); auto tag_set_sf = make_document(kvp("dc", "sf")); mongocxx::read_preference rp; rp.mode(mongocxx::read_preference::read_mode::k_secondary); rp.tags(make_array(tag_set_ny, tag_set_sf).view());
Retryable Reads and Writes
The C++ driver automatically retries certain read and write operations once 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 options to false in your connection
URI. The following example disables retryable reads and writes for a client:
mongocxx::uri uri{"mongodb://localhost:27017/?retryReads=false&retryWrites=false"}; mongocxx::client client{uri};
To learn more about supported retryable read and write operations, see the following guides in the MongoDB Server manual:
Load Balancing
When connecting to a sharded cluster or a replica set, the C++ driver uses load balancing to handle read and write requests. Load balancing allows the driver to distribute these requests across multiple servers, which avoids overwhelming any one server and ensures optimal performance.
When connecting to a sharded cluster, the C++ driver determines the
closest mongos instance by calculating which one has the lowest network
round-trip time. Then, the driver determines the latency window by adding this
mongos's average round-trip time to the localThresholdMS value.
The driver load balances requests across up to two random mongos instances
that fall within the latency window. For each request, the driver chooses the
server with the lower operation load by determining its operationCount
value.
When connecting to a replica set, the C++ driver first selects replica
set members according to your read preference. Then, the driver follows the
same process as described in the preceding paragraph. After calculating the
latency window, the driver selects up to two random replica set members that
fall within the window and chooses the member with the lower operationCount
value to receive the request.
Tip
To learn more about load balancing, see Sharded Cluster Balancer in the MongoDB Server manual.
Local Threshold
The C++ driver uses the local threshold value to calculate the latency window for server selection. This value determines the servers that are eligible to receive read and write requests.
By default, the driver uses only mongos instances or replica set members
whose ping times are within 15 milliseconds of the nearest server. To
distribute reads among servers with higher latencies, set the localThreshold
parameter in your connection URI.
Note
When selecting replica set members from a single mongos instance, the
C++ driver ignores the localThresholdMS option. In this case, use the
localThreshold
command-line option.
The following example connects to a replica set and specifies a local threshold of 35 milliseconds:
mongocxx::uri uri{"mongodb://localhost:27017/?replicaSet=repl0&localThresholdMS=35"}; mongocxx::client client{uri};
In the preceding example, the C++ driver distributes reads among matching members within 35 milliseconds of the closest member's ping time.
Collation
You can specify a collation when you perform read and write operations on a collection.
A collation is a set of language-specific rules for string comparison, such as for letter case and accent marks.
To specify a collation, pass the collation definition to the
collation() method of an options object, then pass this options object to a read or
write operation.
Collation Example
Consider a collection with the following documents:
{ _id: 1, category: "café" }, { _id: 2, category: "cafe" }, { _id: 3, category: "cafE" }
The following example creates a collation that specifies the French locale and ignores
differences between case and letter variants. It then uses this collation to find documents
in which the category field value matches "cafe". Because of the specified collation, the query
returns all three documents.
mongocxx::options::find opts{}; opts.collation(bsoncxx::from_json(R"({"locale": "fr", "strength": 1})")); auto cursor = collection.find(make_document(kvp("category", "cafe")), opts); for(auto&& doc : cursor) { std::cout << bsoncxx::to_json(doc) << std::endl; }
{ "_id": { "$oid" : "1" }, "category": "café" } { "_id": { "$oid" : "2" }, "category": "cafe" } { "_id": { "$oid" : "3" }, "category": "cafE" }
API Documentation
To learn more about any of the classes or methods discussed in this guide, see the following API documentation: