在 MongoDB C++ 客户端中创建到副本集的连接
在@acm's answer 中解释的问题得到解决之前,我找到了解决 C++ 驱动程序的错误连接字符串的解决方法。您可以通过这种方式使用主机和端口向量创建DBClientReplicaSet:
//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);
现在,您可以像使用DBClientConnection 一样使用插入、更新等。为了快速修复,您可以将您对 DBClientConnection 的引用替换为 DBClientBase(它是 DBClientConnection 和 DBClientReplicaSet 的父级)
最后的陷阱:如果您使用 getLastError(),则必须将其与目标数据库名称一起使用,如下所示:
connection.getLastError(std::string("DBName"));
否则它将总是返回“命令失败:必须登录”,如 this JIRA ticket 中所述。
为每个请求设置读取首选项
您有两种方法可以做到这一点:
SlaveOK 选项
它可以将您的读取查询定向到辅助服务器。
它发生在查询选项中,位于DBClientReplicaSet.query() 的参数末尾。选项列在Mongo's official documentation
您要查找的是mongo::QueryOption_SlaveOk,这将允许您在辅助实例上进行读取。
这就是你应该如何调用 query();
connection.query("Database.Collection",
QUERY("_id" << id),
n,
m,
BSON("SomeField" << 1),
QueryOption_SlaveOk);
其中 n 是要返回的文档数(如果您不想要任何限制,则为 0),m 要跳过的数字(默认为 0),下一个字段是您的投影,最后一个是您的查询选项。
要使用多个查询选项,您可以像这样使用bitwise or |:
connection.query("Database.Collection",
QUERY("_id" << id),
n,
m,
BSON("SomeField" << 1),
QueryOption_SlaveOk | QueryOption_NoCursorTimeout | QueryOption_Exhaust);
Query::readPref 选项
Query object has a readPref 方法为特殊查询设置读取首选项。应该为每个查询调用它。
您可以传递不同的参数以获得更多控制。 They are listed here.
所以这就是你应该做的(我没有测试那个原因我现在不能,但它应该可以正常工作)
/* 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);
注意:如果使用了任何 readPref 选项,它应该覆盖 slaveOk 选项。
希望这会有所帮助。