【问题标题】:c++ driver mongodb connection optionsc++驱动mongodb连接选项
【发布时间】:2014-08-22 15:39:17
【问题描述】:

似乎 c++ 驱动程序不接受 mongodb 连接 uri 格式。 没有关于我应该如何创建连接字符串的文档,有什么猜测吗?

我需要连接到具有 3 个服务器的副本集,并设置 readPreference 选项。

【问题讨论】:

  • 嗯,“没有文档”??? api.mongodb.org/cplusplus/current/…
  • 好的,告诉我连接字符串格式在哪里解释:)
  • 在某处有解释,但没有来自相关 C++ API 文档的链接,并且实现存在错误,正如下面的答案中所指出的那样。
  • 也许将此问题重命名为“Connecting to a replica set in MongoDB C++ driver”

标签: c++ mongodb connection-string


【解决方案1】:

在 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(它是 DBClientConnectionDBClientReplicaSet 的父级)

最后的陷阱:如果您使用 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 选项。

希望这会有所帮助。

【讨论】:

  • 嗨,您能否解释一下示例中的读取选项(例如 SlaveOK 等)如何与 query.readPref(mongo::ReadPreference_Nearest, arr);仅次要,仅主要等。我可以同时指定它们吗?我可以只使用 Secondary 而不指定 SlaveOk 吗?谢谢
  • 如果您想要更多控制选项,我认为您可以同时使用 slaveOk 或 readPrefs。它应该类似于Node Mongoclient as explained here。所以 readPrefs 应该覆盖任何 SlaveOk 值。不过,它仍需设置在查询级别。我将编辑我的帖子以添加这些详细信息。
【解决方案2】:

有关连接字符串格式的详细信息,请参阅connection string 文档。

(以下代码链接指向 2.2.3 文件)

要将连接字符串与 C++ 驱动程序一起使用,您应该使用 ConnectionString 类。您首先使用连接字符串调用ConnectionString::parse 静态方法以获取ConnectionString 对象。然后调用ConnectionString::connect 获取DBClientBase 对象,然后您可以使用该对象发送查询。

至于读取首选项,目前我没有看到在 C++ 驱动程序的连接字符串中设置读取首选项的方法,这将排除每个连接的设置。

但是,通过使用标识副本集的字符串调用ConnectionString::parse 返回的DBClientBase 的实现将返回DBClientReplicaSet 的实例。该类在查询中尊重$readPreference,因此您可以在每个查询的基础上设置您的阅读偏好。

【讨论】:

  • 它似乎不接受像文档中描述的“mongodb://...”这样的 uri 连接字符串。这就是问题所在。
  • @user1365836 我刚刚试了一下,你是对的。 mongodb://localhost:27017 之类的连接字符串无法正常工作。但是,要连接到一台机器,只需将localhost:27017 传递给ConnectionString::parse 似乎确实有效。看看删除 mongodb:// 前缀是否效果更好。另外,请在此处提交票证:jira.mongodb.org
  • 它使用像replicaset/ip,ip,ip 或类似的旧格式(你再也找不到doc了!)。我很失望:应该遵循 mongodb 开发的 c++ 驱动程序没有按预期工作。我们应该开一张大票“请让 c++ 驱动程序像在文档中一样工作”。如果可以,请尝试 readPreference 或 secondaryAcceptableLatencyMS 参数!非常失望。
  • @user1365836 我同意不幸的是 C++ 驱动程序与文档不一致,并且我同意它不支持所有选项令人沮丧。但是,您最好的做法是在发现问题时向 10gen 提交工单:它可以帮助开发人员了解他们的工作重点,它可以让您跟踪您关心的问题的进度,并帮助遇到相同问题的其他人问题。因此,我强烈建议您针对上述所有问题提交罚单!
【解决方案3】:

由于当前的 C++ 驱动程序仍然不接受标准的 mongodb 连接 URI,因此我开了一张票: https://jira.mongodb.org/browse/CXX-2 请投票支持它以帮助解决此问题。

【讨论】:

    【解决方案4】:

    似乎您可以通过调用 Query 对象的“readPref”方法在发送读取请求之前设置读取首选项。我还没有找到在 mongo 集合对象上设置读取首选项的方法。

    【讨论】:

    • 哦,我错了,mongo连接对象,不是mongo集合对象。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-07-05
    相关资源
    最近更新 更多