c++ - MongoDB C++ BSONObj 生命周期

标签 c++ mongodb

当使用 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/

相关文章:

C++ 对象实例化

c++ - 模板类中的模板函数

python - 按日期和时间查询存储在 MongoDB 中的数据

c++ - 引用计数的发布-消费排序

c++ - 如果有特定元素,则控制 vector

JavaScript - 如何以 ISODate 格式在 MongoDB 文档中保存日期?

mongodb - 按数组类型查询 - MongoDB

node.js - 从 node.js 连接到 mongodb 时出现 ECONNREFUSED 错误

ruby-on-rails - 将 MongoDB 中的 _id 类型更改为整数是否不好?

c++ - OpenMP omp_get_wtime g++ 32 位