user1365836
user1365836

Reputation: 350

c++ driver mongodb connection options

It seems that c++ drivers doesn't accept mongodb connection uri format. There's no documentation on how i should create connection string, any guess?

I need to connect to a replica set with 3 servers, and set readPreference options.

Upvotes: 3

Views: 4769

Answers (4)

Tiesselune
Tiesselune

Reputation: 1711

Create a connection to a replica set in MongoDB C++ client

Until the problems explained in @acm's answer are resolved, I have found a workaround to the bad Connection Strings of the C++ driver. You can create a DBClientReplicaSet using a vector of hosts and ports this way:

//First create a vector of hosts
//( you can ignore port numbers if yours are default)  

    vector<HostAndPort> hosts;
    hosts.push_back(mongo::HostAndPort("YourHost1.com:portNumber1"));
    hosts.push_back(mongo::HostAndPort("YourHost2.com:portNumber2"));
    hosts.push_back(mongo::HostAndPort("YourHost3.com:portNumber3"));

//Then create a Replica Set DB Client:

    mongo::DBClientReplicaSet connection("YourReplicaSetName",hosts,0);

//Connect to it now:

    connection.connect();

//Authenticate to the database(s) if needed

    std::string errmsg;
    connection.auth("DB1Name","UserForDB1","pass1",errmsg);
    connection.auth("DB2Name","UserForDB2","pass2",errmsg);

Now, you can use insert, update, etc. just as you did with DBClientConnection. For a quick fix, you can replace your references to DBClientConnection with DBClientBase (which is a parent to both DBClientConnection and DBClientReplicaSet)

Last pitfall: if you are using getLastError(), you must use it with the aimed database name like this:

connection.getLastError(std::string("DBName"));

cause otherwise it will always return "command failed: must log in" as described in this JIRA ticket.

Set the read preferences for every request

You have two ways to do that:

SlaveOK option

It lets your read queries be directed to secondary servers.

It takes place in the query options, which are at the end of the parameters of DBClientReplicaSet.query(). The options are listed in Mongo's official documentation

The one you would look for is mongo::QueryOption_SlaveOk, which will allow you to have reads made on secondary instances.

This is how you should call query();

connection.query("Database.Collection",
     QUERY("_id" << id),
     n,
     m,
     BSON("SomeField" << 1),
     QueryOption_SlaveOk);

where n is the number of documents to return (0 if you don't want any limit), m the number to skip (defaults to 0), the next field is your projection and the last your query option.

To use several query option, you can use bitwise or | like this :

connection.query("Database.Collection",
     QUERY("_id" << id),
     n,
     m,
     BSON("SomeField" << 1),
     QueryOption_SlaveOk | QueryOption_NoCursorTimeout | QueryOption_Exhaust);

Query::readPref option

The Query object has a readPref method which sets read preferences for a special query. It should be called for each query.

You can pass different arguments for more control. They are listed here.

So here's what you should do (I did not test that one cause I can't right now but it should work just fine)

/* you should pass an array for the tags. Not sure if this is required.
Anyway, let's create an empty array using the builder. */

BSONArrayBuilder bab;

/* if any, add your tags here */

connection.query("Database.Collection",
     QUERY("_id" << id).readPref(ReadPreference_SecondaryPreferred, bab.arr()),
     n,
     m,
     BSON("SomeField" << 1),
     QueryOption_NoCursorTimeout | QueryOption_Exhaust);

Note: if any readPref option is used, it should override the slaveOk option.

Hope this helped.

Upvotes: 3

Timothy Byrd
Timothy Byrd

Reputation: 139

Since the current C++ drivers still do not accept the standard mongodb connection URIs, I've opened a ticket: https://jira.mongodb.org/browse/CXX-2 Please vote for it to help get this fixed.

Upvotes: 1

user2947556
user2947556

Reputation: 1

it seems like you can set read Preference before send a read request by call "readPref" method of your Query object. I'v not found a way to set read Preference on mongo collection object yet.

Upvotes: 0

acm
acm

Reputation: 12727

Please see the connection string documentation for details on the connection string format.

(code links below are to 2.2.3 files)

To use a connection string with the C++ driver, you should use the ConnectionString class. You first call the ConnectionString::parse static method with a connection string to obtain a ConnectionString object. You then call ConnectionString::connect to obtain a DBClientBase object which you can then use to send queries.

As for read preference, at the moment I do not see a way to set the read preference in the connection string for the C++ driver, which would preclude a per-connection setting.

However, the implementation of DBClientBase returned by calling ConnectionString::parse with a string that identifies a replica set will return you an instance of DBClientReplicaSet. That class honors $readPreference in queries, so you can set your read preference on a per-query basis.

Upvotes: 2

Related Questions