当使用 C++ 客户端库并保留从 cursor->next() 返回的 BSONObj 对象时,后续的新查询(使用相同的连接)是否会以某种方式破坏该对象?我的理解是,它是一个智能指针,并且会一直存在,直到对它的最后一次引用超出范围。然而,实践告诉我,后续查询似乎会破坏该对象。在遍历新查询后访问对象的 hasField/getField 方法时出现段错误。
相关代码如下:
BSONObj DB::getmsg
(
const string &oid
)
{
BSONObj query = BSON("_id" << OID(oid));
auto_ptr<DBClientCursor> cursor = c.query("nsdb.messages", query);
if (cursor->more())
return cursor->next();
throw Exception("could not find object %s", oid.c_str());
}
void DB::getchildren
(
const string &oid,
vector<BSONObj> &children
)
{
BSONObj query = BSON("parent" << oid);
BSONObj fields = BSON("_id" << 1);
auto_ptr<DBClientCursor> cursor =
c.query("nsdb.messages", query, 0, 0, &fields);
while (cursor->more())
children.push_back(cursor->next());
}
void DB::message
(
const string &oid,
string &str,
bool body
)
{
connect();
BSONObjBuilder response;
try
{
BSONObj n = getmsg(oid);
response.append("message", n);
vector<BSONObj> children;
getchildren(oid, children);
if (children.size() > 0)
{
BSONArrayBuilder a;
vector<BSONObj>::iterator i;
for (i = children.begin(); i != children.end(); i++)
{
if (!(*i).isEmpty() && (*i).hasField("_id"))
{
string child = (*i).getField("_id").__oid().str();
a.append("http://127.0.0.1:12356/lts/message/" + child);
}
}
if (a.len() > 0)
response.append("children", a.done());
}
if (body)
{
string fname;
if (n.hasField("fname"))
fname = n.getField("fname").str();
if (fname.empty())
{
throw Exception("no fname field in message record %s",
n.jsonString().c_str());
}
auto_mmapR<const void *, int> m(fname);
response.appendBinData("body", m.size(), BinDataGeneral,
m.get());
}
str = response.obj().jsonString();
}
catch (const DBException &x)
{
throw Exception("%s", x.what());
}
}
如果我移动零件:
string fname;
if (n.hasField("fname"))
fname = n.getField("fname").str();
到调用 getchildren(...) 之前的位置,然后从消息中正确检索 fname 字段,否则抛出异常“消息记录中没有 fname 字段”
最佳答案
好吧,我不太了解你的代码,但简短的回答: - 游标返回的数据在下一次迭代或游标被销毁时失效。 使用“getOwned()”获取 BSONObj 对象的拷贝:
cursor->next().getOwned();
关于c++ - MongoDB C++ BSONObj 生命周期,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19638318/