我有一个使用mongo shell创建的MongoDB 3.0.7数据库。以下工作正常:
% mongo test
> vs = db.myCollection.findOne({"somefield.subfield": "somevalue"})
但是当我在C ++中这样做时:
mongocxx::instance inst{};
mongocxx::client conn{};
auto db = conn["test"];
bsoncxx::stdx::optional< bsoncxx::document::value> docObj;
try {
docObj =
db["myCollection"]
.find_one(document{} <<
"somefield.subfield" << "someValue" <<
bsoncxx::builder::stream::finalize);
} catch (mongocxx::exception::operation e) {
std::cerr << "Retrieval failed (and exception thrown)";
}
if (docObj == bsoncxx::stdx::nullopt)
std::cerr << "Failed to find object";
我得到“找不到对象”。我在这里缺少什么?
更新: 2015年11月23日,10:00
我安装了最新的cxx驱动程序(0.3.0),并进行了以下更改:
mongocxx::instance inst{};
mongocxx::client *connPtr;
bsoncxx::stdx::string_view connectionString("mongodb://localhost");
connPtr = new mongocxx::client(mongocxx::uri(connectionString));
auto db = connPtr->database("test");;
bsoncxx::stdx::optional< bsoncxx::document::value> docObj;
try {
docObj =
db["myCollection"]
.find_one(document{} <<
"somefield.subfield" << "someValue" <<
bsoncxx::builder::stream::finalize);
} catch (mongocxx::exception::operation e) {
std::cerr << "Retrieval failed (and exception thrown)";
}
if (docObj == bsoncxx::stdx::nullopt)
std::cerr << "Failed to find object";
我回到了完全相同的事情。调用db.list_collections(document{})
不会检索到任何结果。
答案 0 :(得分:1)
bsoncxx库有两种文档类型,视图和值。 document::value
包含实际的文档数据,而document::view
只是对某些基础value
的引用。 Value
必须比使用它们的view
更长。
新的c ++ 11驱动程序中存在一个错误,其中传递document::value
的方式。此代码生成document::value
:
document{} << "someField" << "someValue" << finalize;
collection.find_one()
方法将document::view
和document::values
隐式转换为document::views
。不幸的是,这意味着如果您在调用find_one()时动态构建文档,如上所述,您可以自己开枪:
collection.find_one(document{} << "someField" << "someValue" << finalize);
finalize
制作一个临时document::value
,然后find_one将其转换为document::view
。临时的value
会被丢弃在地板上,让view
value
- 更少,就像一个悬垂的指针。
解决方法是在单独的调用中创建您的值,并保留它:
document::value doc = document{} << "someField" << "someValue" << finalize;
collection.find_one(doc.view());
我怀疑这是导致查询失败的原因;如果没有,那么就可以使你的代码具有弹性!
您可以跟踪this ticket以查找此问题的真正修复方法。