建立连接:
try { mongo::DBClientConnection c; c.connect("localhost"); std::cout << "connected ok" << std::endl; } catch( const mongo::DBException &e ) { std::cout << "caught " << e.what() << std::endl; }
插值
往数据库中保存数据必须创建BSONObj类的对象,BSONObj下各组件都可以叫做BSONElement对象。使用BSONObjBuilder构造各种BSON对象,用BSONObjIterator来遍历各BSON对象。
以下构造的BSON对象——“person”包含有name和age,我们这样调用:
BSONObjBuilder b; b.append("name", "Joe"); b.append("age", 33); BSONObj p = b.obj();
更简明的方式是:
BSONObj p = BSONObjBuilder().append("name", "Joe").append("age", 33).obj();
还可以使用stream-oriented语法:
BSONObjBuilder b; b << "name" << "Joe" << "age" << 33; BSONObj p = b.obj();
而使用宏BSON则是最紧凑的:
BSONObj p = BSON( "name" << "Joe" << "age" << 33 );
通过使用GENOID 这个helper标记可以为对象增加一个object id。 GENOID (产生mongo::IOD类型值)字段是可选,若没有显式列出,服务端插入时会自动增加一个_id字段:
BSONObj p = BSON( GENOID << "name" << "Joe" << "age" << 33 ); // result is: { _id : ..., name : "Joe", age : 33 }
若是使用non-stream构建语法创建,则GENOID应放在生成对象的开始位置:
BSONObj p = BSONObjBuilder().genOID().append("name","Joe").append("age",33).obj();
构建后即可将person BSON对象这样插入persons collection:
c.insert("tutorial.persons", p);
以下代码获取persons collection的所有对象,并逐一显式
cout << "count:" << c.count("tutorial.persons") << endl; //先输出对象数量 auto_ptr<DBClientCursor> cursor = c.query("tutorial.persons", BSONObj()); //一个空的BSON对象 while (cursor->more()) cout << cursor->next().toString() << endl;
BSONObj() 指代一个空BSON对象——即表示{},而query条件为空即表示搜索全表。
使用BSONObj::toString可获得关于对象的概要JSON String,要想获得完整输出,应用BSONObj::jsonString,获得单个字段的字符串类型的值则使用
.getStringField("name"),函数原型及相关可参见MongoDB 2.4.0 API Doc[BSONObj]。
若要设置query条件,可如下构造一个QUERY类对象:
auto_ptr<DBClientCursor> cursor = c.query("tutorial.persons", QUERY("age" << age ));
排序
进一步若要使返回的结果集按name的字母序排序,则可通过使用Query::sort()来给query表达式增加一个更改项(modifier):
auto_ptr<DBClientCursor> cursor = c.query("tutorial.persons", QUERY("age" << age ).sort("name"));
索引
若想用age字段作为索引,来加速查询,则可以这样:
c.ensureIndex("tutorial.persons", fromjson("{age:1}"));
ensureIndex会先做同样的索引存在检测,若无则创建。ensureIndex是智能的,不会向服务端重复发送,因而就算多次调用它也是安全的。
fromjson函数用于把JSON String转换为BSON String,某些情况下这种方式指定BSON更方便。
而用BSON宏的方式则为:
c.ensureIndex("tutorial.persons", BSON( "age" << 1 ));
修改
通过使用Update()方法修改数据库(将name为Joe者的age改为33、visits字段值增1):
c.update("tutorial.persons", BSON("name" << "Joe" << "age" << 33), BSON("$inc" << BSON( "visits" << 1)));
再举一例:
SQL原型为: UPDATE users SET a=a+2 WHERE b='q'
对应 Mongo Shell: db.users.update({b:'q'}, {$inc:{a:2}},false,true)
C++代码:
c.update("mydb.users", QUERY("b"<<"q"), BSON("$inc"<<BSON("a"<<2)), false, true); //最后两项表示是否upsert、是否批修改 // optionally: string err = c.getLastError(); bool ok = err.empty();
删除
使用remove()删除文档:
c.remove("tutorial.persons", QUERY("name"<<"Tim"));
先看代码:
#include <iostream> #include <cstdlib> #include "mongo/client/dbclient.h" using namespace mongo; using namespace std; ///////////////////////////////////////////////////////////////////// // @notes: print all members of one collection // @param: conn -- the connection to be queried // @ coll -- collection name with format ns.collecion ///////////////////////////////////////////////////////////////////// void printAllMemsOfOneColl(DBClientConnection& conn, string coll) { cout<<"count:"<<conn.count(coll)<<endl; auto_ptr<DBClientCursor> cursor = conn.query(coll, BSONObj()); while (cursor->more()) cout<<cursor->next().toString()<<endl; } //////////////////////////////////////////////////////////////////// // @notes: print members of specified age. //////////////////////////////////////////////////////////////////// void printIfAge(DBClientConnection& c, int age) { auto_ptr<DBClientCursor> cursor = c.query("tutorial.persons", BSON("age"<<age)); while (cursor->more()){ BSONObj p = cursor->next(); cout<<p.getStringField("name")<<endl; } } ////////////////////////////////////////////////////////////////////////////// // @notes: sort result by name ////////////////////////////////////////////////////////////////////////////// void printIfAgeAndSortByName(DBClientConnection& c, int age) { auto_ptr<DBClientCursor> cursor = c.query("tutorial.persons", MONGO_QUERY("age"<<age).sort("name")); while (cursor->more()){ BSONObj p = cursor->next(); cout<<"sort by name of age "<<age<<": "<<p.getStringField("name")<<endl; } } ////////////////////////////////////////////////////////////////////////////////// // @update: update interface //////////////////////////////////////////////////////////////////////////// void updateElement(DBClientConnection& c, string dbConn) { c.update(dbConn, MONGO_QUERY("name"<<"loe23"<<"age"<<53), BSON("$inc"<<BSON("visits"<<1)), 1); } ////////////////////////////////////////////////////////////////////////////// //@notes: remove elements ////////////////////////////////////////////////////////////////////////////// void removeElementsWithSpecName(DBClientConnection& c, string dbConn, string name) { c.remove(dbConn, MONGO_QUERY("name"<<name), 0); } int main() { DBClientConnection conn; BSONObj p = BSONObjBuilder().append("name", "koe23").append("age", 23).obj(); try { mongo::client::initialize(); HostAndPort hp("localhost", 10002); string err; conn.connect(hp, err); cout << "connected ok." << endl; } catch( DBException &e ) { cout << "caught " << e.what() << endl; } conn.insert("tutorial.persons", p); printAllMemsOfOneColl(conn, "tutorial.persons"); printIfAge(conn, 13); printIfAgeAndSortByName(conn, 23); updateElement(conn, "tutorial.persons"); removeElementsWithSpecName(conn, "tutorial.persons", "Joe"); removeElementsWithSpecName(conn, "tutorial.persons", "Joe22"); removeElementsWithSpecName(conn, "tutorial.persons", "Goe23"); return 0; }
二。 API说明:
说明: * IN表示输入参数; * OUT表示输出参数;
(1)构造函数:
DBClientConnection(bool auto_connect, 0, double so_timeout);
auto_connect(IN):连接失败后自动重连
so_timeout(IN):非连接超时,tcp的读写超时
(2)连接mongo:
bool connect(HostAndPort server, &string errmsg);
返回值:成功/失败
errmsg(OUT):出错信息
(3)查询
auto_ptr query(const string &ns, Query query, int nToReturn, int nToSkip,const BSONObj *fieldsToReturn, int queryOptions , int batchSize);
返回值:结果集
ns(IN):命名空间,db_name.collection_name
query(IN):查询的条件,相当于mysql中的where
nToReturn:返回结果条数,相当于mysql中的limit
nToSkip:跳过的结果条数,相当于mysql中的offset
fieldsToReturn:返回列集合
queryOptions:详见QueryOptions这个枚举,填0即可
batchSize:未说明
示例:
string db = "shool";
string collection = "student";
Query condition = MONGO_QUERY("age"<<20);
int limit = 10;
int offset = 5;
BSONObj columns = BSON("uid"<<1<<"name"<<1);
auto_ptr cursor;
cursor = pConn->query(db+"."+collection, condition, limit, offset, columns, 0, 0);
其效果相当于:
select uid,name from shool.student where age=20 limit 5,10;
对结果集的操作:
int uid=0;
string name="";
while(cursor->more())
{
BSONObj p = cursor->next();
uid = p["uid"].Int();
name = p["name"].String();
count << uid << " " << name << endl;
}
(4)插入
void insert(const string &ns, BSONObj obj, int flags);
ns(IN):命名空间,db_name.collection_name
obj(IN):插入的列
flags(IN):详见API文档,默认填零即可
示例:
BSONObj insert = BSON("uid"<<10001<<"name"<<"skean1017");
pConn->insert(db+"."+collection, insert, 0);
其效果相当于:
insert into shool.student (uid, name) values (10001, “skean1017″);
(5)删除
void remove(const string &ns, Query query, bool justOne);
ns(IN):命名空间,db_name.collection_name
query(IN):查询条件
justOne(IN):是否只删除匹配的第一条
示例:
Query query = MONGO_QUERY("name"<<"skean1017");
pConn->remove(db+"."+collection, query, true);
其效果相当于:
delete from shool.student where name=”skean1017″;
(6)修改
void update(const string &ns , Query query , BSONObj obj , bool upser , bool multi);
ns(IN):命名空间,db_name.collection_name
query(IN):查询条件
obj(IN):修改后的值
upser(IN):是否upser,如果不存在则插入记录
multi(IN):是否为符合文档
示例:
Query query = MONGO_QUERY("uid"<<10001);
BSONObj obj = BSON("$set"<update(db+"."+collection, query, obj, false, false);
其效果相当于:
update shool.student set name=”habadog1203″ where uid=10001;
(7) Query 与BSONObj
在看到的代码中,很多需要Query作为参数的位置,使用了BSONObj做隐式转换来代替。
(8) findOne
BSONObj obj = conn->findOne( dbname, BSONObjBuilder().append( "_id" , id ).obj());
if( !obj.isEmpty() ){
value = obj.getStringField("value");
}