[笔记]MongoDB 二(Linux下MongoDB API C++编程)

一、连接类

  DBClientConnection,派生自DBClientBase。DBClientBase类是实现query, update, insert, remove等功能。

  构造函数:DBClientConnection(bool _autoReconnect=false, DBClientReplicaSet* cp=0, double so_timeout=0)

    _autoReconect是否自动重连,默认false

    cp不需要关心,默认值

    so_timeout超时时间,单位是秒

  连接函数:bool connect(const char *hostname, string &errmsg)

    hostname 主机,127.0.0.1,127.0.0.1:5555

    errmsg 错误信息,传出

二、删除文档

  void remove(const string &ns, Query q, bool justOne=0)

    ns 库名.集合名

    q 是一个查询条件。Query是一个类,利用构造函数Query(const char *json);构造。

    justOne 是否删除一条,默认false

三、新增文档

  void insert(const string &ns, BSONObj obj, int flag=0)

    ns 库名.集合名

    BSONObj obj:

      1、通过BSONObjBuilder构造

        

 1 //通过BSONObjBuilder.obj()生成BSONObj
 2 
 3 //第一种形式
 4 BSONObjBuilder b1;
 5 //{id:1,name:'haha'}
 6 b1.append("id",1);
 7 b1.append("name","haha");
 8 /*
 9 BSONObj obj() {
10             bool own = owned();
11             massert( 10335 , "builder does not own memory", own );
12             doneFast();
13             BSONObj::Holder* h = (BSONObj::Holder*)_b.buf();
14             decouple(); // sets _b.buf() to NULL
15             return BSONObj(h);
16         }
17 */
18 DBClientConnection.insert("dbName.collectionName",b1.obj());
19 
20 //第二种形式
21 BSONObjBuilder b2;
22 //{id:2,name:'hehe'}
23 /*
24     template<class T>
25     BSONObjBuilder& operator<<( T value );
26 */
27 b2<<"id"<<2<<"name"<<"hehe";
28 //余下同上
29 
30 //第三种形式
31 /*
32 #define BSON(x) (( mongo::BSONObjBuilder(64) << x ).obj())
33 */
34 //{id:3,name:'hahe'}
35 BSONObjBuilder b3=BSON("id"<<3<<"name"<<hahe");

      2、通过Query构造

        

 1 //{id:4,name:'heha'}
 2 Query ins("{id:4,name:'heha'}");
 3 /*
 4 class Query {
 5     public:
 6         BSONObj obj;
 7         Query() : obj(BSONObj()) { }
 8         Query(const BSONObj& b) : obj(b) { }
 9         Query(const string &json);
10         Query(const char * json);
11 */
12 insert("dbName.collectionName",ins.obj);

 四、修改文档

  void update(const string &ns, Query query, BSONObj obj, bool upsert = false, bool multi = false);

  ns 库名.集合名

  query 查询的条件

  obj 更新的内容

  upsert 如果条件不成立是否新增

  multi 是否更新多条

  

1 //查询条件
2 Query query("{id:1}");
3 //更新内容
4 Query bobj("{name:'hehe'}");
5 update("dbName.collectionName",query,bobj.obj);

五、查询文档

  virtual auto_prt<DBClientCursor> query(const string &ns, Query query=Query(), int nToReturn =0, int nToSkip=0, const BSONObj *fieldsToReturn=0, int queryOptions=0, int batchSize=0)

  auto_prt<DBClientCursor> 智能指针,自动释放<>内部的内存数据

    DBClientCursor类,存放查询结果。more()判断调用next是否安全。next()返回BSONObj对象

      DBClientCursor部分源码:

/** Queries return a cursor object */
    class DBClientCursor : public DBClientCursorInterface {
    public:
        /** If true, safe to call next().  Requests more from server if necessary. */
        bool more();

        /** If true, there is more in our local buffers to be fetched via next(). Returns
            false when a getMore request back to server would be required.  You can use this
            if you want to exhaust whatever data has been fetched to the client already but
            then perhaps stop.
        */
        int objsLeftInBatch() const { _assertIfNull(); return _putBack.size() + batch.nReturned - batch.pos; }
        bool moreInCurrentBatch() { return objsLeftInBatch() > 0; }

        /** next
           @return next object in the result cursor.
           on an error at the remote server, you will get back:
             { $err: <string> }
           if you do not want to handle that yourself, call nextSafe().
        */
        BSONObj next();

 

    ns,query  同前

    nToReturn 返回记录数

    nToSkip 跳过记录数

    fieldsTOReturn 要返回的字段

DBClientConnection conn(false,0,3);
std::string errmsg;
if (!conn.connect("localhost:27018", errmsg))
{
    cout << "connect to mongo err" << endl;
    return -1;
}
auto_ptr<DBClientCursor> cursor = conn.query("dbName.collectionName", Query("{}"));

    读取查询结果:

      BSONObj重载了<<

        部分源码:

inline std::ostream& operator<<( std::ostream &s, const BSONObj &o ) {
        return s << o.toString();
    }

inline std::string BSONObj::toString( bool isArray, bool full ) const {
        if ( isEmpty() ) return "{}";
        StringBuilder s;
        toString(s, isArray, full);
        return s.str();
    }

inline void BSONObj::toString( StringBuilder& s,  bool isArray, bool full, int depth ) const {
        if ( isEmpty() ) {
            s << "{}";
            return;
        }

        s << ( isArray ? "[ " : "{ " );
        BSONObjIterator i(*this);
        bool first = true;
        while ( 1 ) {
            massert( 10327 ,  "Object does not end with EOO", i.moreWithEOO() );
            BSONElement e = i.next( true );
            massert( 10328 ,  "Invalid element size", e.size() > 0 );
            massert( 10329 ,  "Element too large", e.size() < ( 1 << 30 ) );
            int offset = (int) (e.rawdata() - this->objdata());
            massert( 10330 ,  "Element extends past end of object",
                     e.size() + offset <= this->objsize() );
            e.validate();
            bool end = ( e.size() + offset == this->objsize() );
            if ( e.eoo() ) {
                massert( 10331 ,  "EOO Before end of object", end );
                break;
            }
            if ( first )
                first = false;
            else
                s << ", ";
            e.toString( s, !isArray, full, depth );
        }
        s << ( isArray ? " ]" : " }" );
    }

      读取指定字段内容

        BSONObj::getField(const StringData& name)

        源码:

inline BSONElement BSONObj::getField(const StringData& name) const {
    BSONObjIterator i(*this);
    while ( i.more() ) {
        BSONElement e = i.next();
        if ( strcmp(e.fieldName(), name.data()) == 0 )
            return e;
    }
    return BSONElement();
}

        BSONElement部分源码:

class BSONElement {
public:
    /** These functions, which start with a capital letter, throw a UserException if the
        element is not of the required type. Example:

        std::string foo = obj["foo"].String(); // std::exception if not a std::string type or DNE
    */
    std::string String()        const { return chk(mongo::String).valuestr(); }
    Date_t Date()               const { return chk(mongo::Date).date(); }
    double Number()             const { return chk(isNumber()).number(); }
    double Double()             const { return chk(NumberDouble)._numberDouble(); }
    long long Long()            const { return chk(NumberLong)._numberLong(); }
    int Int()                   const { return chk(NumberInt)._numberInt(); }
    bool Bool()                 const { return chk(mongo::Bool).boolean(); }
    std::vector<BSONElement> Array() const; // see implementation for detailed comments
    mongo::OID OID()            const { return chk(jstOID).__oid(); }
    void Null()                 const { chk(isNull()); } // throw UserException if not null
    void OK()                   const { chk(ok()); }     // throw UserException if element DNE

        读取的字段不存在,程序会出现异常,需要调用hasField(char*)或者hasElement(char*)判断是否有该元素

       示例

while (cursor->more())
{//判断是否有下一条
    mongo::BSONObj obj = cursor->next();//取下一条记录,为BSONObj格式
    //cout << obj << endl;
    //解析数据
    cout << "id:" << obj.getField("id").Number() << ",name:" << obj.getField("name").String();
    if (obj.hasElement("age"))
        {//是否存在该元素
        cout << ",age:" << obj.getField("age").Number();
    }
    
    cout << endl;
}

 

posted @ 2019-09-27 13:36  qetuo[  阅读(683)  评论(0编辑  收藏  举报