MongoDB的c++封装api
2016-03-11 15:02
656 查看
为了方便使用,用mongodb的c驱动写了个访问mongodb的c++api接口。提供了bson参数和json参数作为函数实参的一些api。下面列出一些基础的api接口,而逻辑接口是在这些基础接口上使用的。所有的api接口以成员函数的形式存在于lbs代理会话对象中。该对象保存连接到mongodb实例的长连接。以后如若要做地理分片也可以在改会话对象中哈希到不同分片的mongodb实例。
对于很多系统是提供json形式的数据的,提供json参数的api能更容易开发逻辑。bson格式是mongodb的数据传输形式,也是mongodb 的c驱动api提供的原生参数,直接使用bson参数接口有利于提高处理效率。
下面列出的api的使用方式在注释中也注明了。
相关的mongodb的c驱动,可参考官方文档mongoc api:http://api.mongodb.org/c/current/
删除所有符合条件的文档
阐述满足条件的所有的文档
对于很多系统是提供json形式的数据的,提供json参数的api能更容易开发逻辑。bson格式是mongodb的数据传输形式,也是mongodb 的c驱动api提供的原生参数,直接使用bson参数接口有利于提高处理效率。
下面列出的api的使用方式在注释中也注明了。
相关的mongodb的c驱动,可参考官方文档mongoc api:http://api.mongodb.org/c/current/
1.初始化连接
配置数据库连接,在初始化时建立长连接bool LbsProxySession::Init(const loss::CJsonObject& conf) { if (boInit) { return true; } std::string dbip; int dbport; if (!conf.Get("dbip", dbip) || !conf.Get("dbport", dbport) || !conf.Get("group_dbname", group_dbname) || !conf.Get("group_tbname", group_tbname) || !conf.Get("user_dbname", user_dbname) || !conf.Get("user_tbname", user_tbname) || !conf.Get("near_dis", near_dis)) { return false; } snprintf(connectStr, sizeof(connectStr), "mongodb://%s:%d/", dbip.c_str(), dbport); mongoc_init(); client = mongoc_client_new(connectStr); //"mongodb://localhost:27017/" if (!client) { return false; } boInit = true; return true; }
2.bson参数操作数据库CRUD
2.1插入请求
/* (1)构建请求 bson_oid_t oid; bson_t *doc; doc = bson_new (); bson_oid_init (&oid, NULL); BSON_APPEND_OID (doc, "_id", &oid);//文档id BSON_APPEND_UTF8 (doc, "hello", "world");//hello字段 (2)插入操作 InsertDoc("mydb", "mycoll",doc) (3)销毁请求 bson_destroy (doc); * */ bool LbsProxySession::InsertDoc(const char*db, const char*tb, const bson_t *doc) { mongoc_collection_t *collection = mongoc_client_get_collection(client, db, tb); //插入到数据库db的集合coll中 if (!mongoc_collection_insert(collection, MONGOC_INSERT_NONE, doc, NULL, &error)) { char *docStr = bson_as_json(doc, NULL); LOG4CPLUS_ERROR_FMT(GetLogger(), "mongoc_collection_insert failed,cond:%s,error: %s\n", docStr, error.message); bson_free(docStr); mongoc_collection_destroy(collection); return false; } mongoc_collection_destroy(collection); return true; }
2.2查询操作
/* (1)查询条件 bson_t *cond; cond = bson_new (); mongoc_cursor_t *cursor(NULL); (2)查询,返回游标cursor SearchDocs("mydb","mycoll",cond,cursor) (3)获取查询结果 const bson_t *doc; char *str; while (mongoc_cursor_next (cursor, &doc)) { str = bson_as_json (doc, NULL); printf ("%s\n", str); bson_free (str); } (4) 销毁请求句柄 bson_destroy (cond); mongoc_cursor_destroy (cursor); * */ bool LbsProxySession::SearchDocs(const char*db, const char*tb, const bson_t *cond, mongoc_cursor_t *&cursor, unsigned int skip, unsigned int limit, unsigned int batch_size, const bson_t *fields) { mongoc_collection_t *collection = mongoc_client_get_collection(client, db, tb); cursor = mongoc_collection_find(collection, MONGOC_QUERY_NONE, skip, limit, batch_size, cond, fields, NULL); //获取查询对象查询后的结果 if (!cursor) { char *condStr = bson_as_json(cond, NULL); LOG4CPLUS_ERROR_FMT(GetLogger(), "SearchDocs mongoc_collection_find failed,cond:%s,error: %s\n", condStr, error.message); bson_free(condStr); mongoc_collection_destroy(collection); return false; } mongoc_collection_destroy(collection); return true; }
2.3更新操作
条件查询/* (1)更新条件和更新数据,如db.a.update({"_id" : ObjectId("55ef549236fe322f9490e17b")},{"$set":{"key":"new_value","updated":true}}) bson_t *cond = BCON_NEW ("_id", BCON_OID (&oid));//条件为id "_id" : ObjectId("55ef549236fe322f9490e17b") bson_t *updatedoc = BCON_NEW ("$set", "{", "key", BCON_UTF8 ("new_value"), "updated", BCON_BOOL (true), "}");//{"$set"} (2)更新文档 UpdateDoc("mydb","mycoll",cond,updatedoc) (3)销毁请求 if (query) bson_destroy (query); if (update) bson_destroy (update); * */ bool LbsProxySession::UpdateDoc(const char*db, const char*coll, const bson_t *cond, const bson_t *updatedoc) { mongoc_collection_t *collection = mongoc_client_get_collection(client, db, coll); //指定数据库和集合(即表) if (!collection) //mongoc_client_get_collection分配失败会执行abort,实际上可以不检查 { LOG4CPLUS_ERROR_FMT(GetLogger(), "UpdateDoc mongoc_client_get_collection failed:%s\n", error.message); return false; } if (!mongoc_collection_update(collection, MONGOC_UPDATE_MULTI_UPDATE, cond, updatedoc, NULL, &error)) //MONGOC_UPDATE_MULTI_UPDATE更新所有符合结果的 { char *condStr = bson_as_json(cond, NULL); LOG4CPLUS_ERROR_FMT(GetLogger(), "UpdateDoc mongoc_collection_update failed,cond:%s,error: %s\n", condStr, error.message); bson_free(condStr); mongoc_collection_destroy(collection); return false; } mongoc_collection_destroy(collection); return true; }
2.4 更新插入操作
没有该条件的就插入,否则就更新/* (1)更新条件和更新数据命令(没有则插入) bson_t *cond = BCON_NEW ("_id", BCON_OID (&oid));//条件为id "_id" : ObjectId("55ef549236fe322f9490e17b") bson_t *updatedoc = BCON_NEW ("$set", "{", "key", BCON_UTF8 ("new_value"), "updated", BCON_BOOL (true), "}"); (2)更新文档 UpsertDoc("mydb","mycoll",cond,updatedoc) (3)销毁请求 if (cond) bson_destroy (cond); if (updatedoc) bson_destroy (updatedoc); * */ bool LbsProxySession::UpsertDoc(const char*db, const char*coll, const bson_t *cond, const bson_t *updatedoc) { mongoc_collection_t *collection = mongoc_client_get_collection(client, db, coll); //指定数据库和集合(即表) if (!collection) { LOG4CPLUS_ERROR_FMT(GetLogger(), "UpdateDoc mongoc_client_get_collection failed:%s\n", error.message); return false; } if (!mongoc_collection_update(collection, MONGOC_UPDATE_UPSERT, cond, updatedoc, NULL, &error)) //MONGOC_UPDATE_UPSERT 更新 { char *condStr = bson_as_json(cond, NULL); LOG4CPLUS_ERROR_FMT(GetLogger(), "UpsertDoc mongoc_collection_update failed,cond:%s,error: %s\n", condStr, error.message); bson_free(condStr); //调用的是free mongoc_collection_destroy(collection); return false; } mongoc_collection_destroy(collection); return true; }
2.5删除请求
删除第一个符合条件的文档/* (1)构建请求 bson_t *cond = bson_new (); BSON_APPEND_OID (doc, "_id", &oid); (2)删除操作 DeleteDoc("mydb","mycoll",cond) (3)销毁请求 bson_destroy (cond); * */ bool LbsProxySession::DeleteDocOnce(const char*db, const char*coll, const bson_t *cond) { mongoc_collection_t *collection = mongoc_client_get_collection(client, db, coll); //指定数据库和集合 if (!collection) { LOG4CPLUS_ERROR_FMT(GetLogger(), "DeleteDoc mongoc_client_get_collection failed"); return false; } if (!mongoc_collection_remove(collection, MONGOC_REMOVE_SINGLE_REMOVE, cond, NULL, &error)) { char *condStr = bson_as_json(cond, NULL); LOG4CPLUS_ERROR_FMT(GetLogger(), "Delete failed,cond:%s,error: %s\n", condStr, error.message); bson_free(condStr); mongoc_collection_destroy(collection); return false; } mongoc_collection_destroy(collection); return true; }
删除所有符合条件的文档
bool LbsProxySession::DeleteDocAll(const char*db, const char*coll, const bson_t *cond) { mongoc_collection_t *collection = mongoc_client_get_collection(client, db, coll); //指定数据库和集合 if (!collection) { LOG4CPLUS_ERROR_FMT(GetLogger(), "DeleteDoc mongoc_client_get_collection failed"); return false; } if (!mongoc_collection_remove(collection, MONGOC_REMOVE_NONE, cond, NULL, &error)) { char *condStr = bson_as_json(cond, NULL); LOG4CPLUS_ERROR_FMT(GetLogger(), "Delete failed,cond:%s,error: %s\n", condStr, error.message); bson_free(condStr); mongoc_collection_destroy(collection); return false; } mongoc_collection_destroy(collection); return true; }
2.6计数请求
对符合条件的文档数进行计数。在分页显示时常用该操作。/* (1)构建请求 bson_t *cond = bson_new_from_json ((const uint8_t *)"{\"hello\" : \"world\"}", -1, &error);//构造计数条件 (2)执行计数请求 long long count(0); Count("mydb", "mycoll",cond,count) * */ bool LbsProxySession::Count(const char*db, const char*coll, const bson_t *cond, long long &count) { mongoc_collection_t *collection = mongoc_client_get_collection(client, db, coll); //指定数据库和集合 if (!collection) { LOG4CPLUS_ERROR_FMT(GetLogger(), "Count mongoc_client_get_collection failed"); return false; } count = mongoc_collection_count(collection, MONGOC_QUERY_NONE, cond, 0, 0, NULL, &error); if (count < 0) { char *condStr = bson_as_json(cond, NULL); LOG4CPLUS_ERROR_FMT(GetLogger(), "mongoc_collection_count failed,cond:%s,error: %s\n", condStr, error.message); bson_free(condStr); mongoc_collection_destroy(collection); return false; } mongoc_collection_destroy(collection); return true; }
2.7命令请求
mongodb有一系列的自有的命令,包括管理类命令、地理信息命令等。/* (1)构建命令请求 bson_t *command; command = BCON_NEW ("collStats", BCON_UTF8 ("mycoll")); (2)执行命令 bson_t reply;//执行命令返回 Command("mydb", "mycoll",command) (3)获取返回结果 char *str = bson_as_json (&reply, NULL);//输出执行命令后的结果 printf ("%s\n", str); bson_free (str); (4)销毁请求 bson_destroy (command); bson_destroy (&reply); * */ bool LbsProxySession::Command(const char*db, const char*coll, const bson_t *command, bson_t &reply) { mongoc_collection_t *collection = mongoc_client_get_collection(client, db, coll); if (!collection) { LOG4CPLUS_ERROR_FMT(GetLogger(), "Count mongoc_client_get_collection failed"); return false; } if (!mongoc_collection_command_simple(collection, command, NULL, &reply, &error)) { char *commandStr = bson_as_json(command, NULL); LOG4CPLUS_ERROR_FMT(GetLogger(), "failed to run command:%s,error: %s\n", commandStr, error.message); bson_free(commandStr); mongoc_collection_destroy(collection); return false; } mongoc_collection_destroy(collection); return true; }
3.json参数操作数据库CRUD
3.1插入请求
int LbsProxySession::InsertDoc(const char*db, const char*tb, const loss::CJsonObject &insertdObj) { int retCode(ERR_OK); LOG4CPLUS_DEBUG_FMT(GetLogger(), "insertdObj json(%s)", insertdObj.ToString().c_str()); //插入的文档 bson_t * insertddoc = GetBsonDoc(insertdObj, error); DebugOutPutBson(GetLogger(), insertddoc, "InsertDoc insertddoc"); if (!insertddoc) { LOG4CPLUS_WARN_FMT(GetLogger(), "insertdObj convert to bson failed(%s)", insertdObj.ToString().c_str()); retCode = ERR_REQ_MISS_PARAM; return retCode; } //有则更新,无则插入 if (!InsertDoc(db, tb, insertddoc)) { SAFE_DESTROY_BSON(insertddoc); retCode = ERR_OPERATOR_MONGO_ERROR; return retCode; } SAFE_DESTROY_BSON(insertddoc); return retCode; }
3.2查询请求
int LbsProxySession::SearchDocs(const char*db, const char*tb, const loss::CJsonObject &condObj, std::vector<loss::CJsonObject> &replyObjs, const loss::CJsonObject &fieldsObj, unsigned int skip, unsigned int limit, unsigned int batch_size) { int retCode(ERR_OK); LOG4CPLUS_DEBUG_FMT(GetLogger(), "condObj json(%s)", condObj.ToString().c_str()); //查询的条件 bson_t * condDoc = GetBsonDoc(condObj, error); DebugOutPutBson(GetLogger(), condDoc, "SearchDocs condDoc"); if (!condDoc) { LOG4CPLUS_WARN_FMT(GetLogger(), "condObj convert to bson failed(%s)", condObj.ToString().c_str()); retCode = ERR_REQ_MISS_PARAM; return retCode; } //查询的fields bson_t * fieldsDoc(NULL); if (!fieldsObj.ToString().empty()) { fieldsDoc = GetBsonDoc(fieldsObj, error); if (!fieldsDoc) { LOG4CPLUS_ERROR_FMT(GetLogger(), "SearchDocs get fieldsDoc failed,error: %s\n", error.message); retCode = ERR_REQ_MISS_PARAM; return retCode; } } DebugOutPutBson(GetLogger(), condDoc,"SearchDocs condDoc"); if(fieldsDoc) { DebugOutPutBson(GetLogger(), fieldsDoc,"SearchDocs fieldsDoc"); } else { LOG4CPLUS_DEBUG_FMT(GetLogger(), "SearchDocs all fields"); } mongoc_cursor_t *cursor(NULL); if (!SearchDocs(db, tb, condDoc, cursor, skip, limit, batch_size, fieldsDoc)) { LOG4CPLUS_WARN_FMT(GetLogger(), "SearchDocs failed"); SAFE_DESTROY_BSON(condDoc); SAFE_DESTROY_BSON(fieldsDoc); retCode = ERR_OPERATOR_MONGO_ERROR; return retCode; } replyObjs.clear(); loss::CJsonObject tmpReplyObj; //遍历结果 const bson_t *doc; char *str; while (mongoc_cursor_next(cursor, &doc)) { str = bson_as_json(doc, NULL); tmpReplyObj.Clear(); tmpReplyObj.Parse(str); replyObjs.push_back(tmpReplyObj); LOG4CPLUS_DEBUG_FMT(GetLogger(), "reply:%s\n", str); bson_free(str); } mongoc_cursor_destroy(cursor); SAFE_DESTROY_BSON(condDoc); SAFE_DESTROY_BSON(fieldsDoc); return retCode; }
3.3更新请求
int LbsProxySession::UpdateDoc(const char*db, const char*tb, const loss::CJsonObject &condObj, const loss::CJsonObject &updatedObj) { int retCode(ERR_OK); LOG4CPLUS_DEBUG_FMT(GetLogger(), "condObj json(%s),updatedObj json(%s)", condObj.ToString().c_str(), updatedObj.ToString().c_str()); //更新的条件 bson_t * conddoc = GetBsonDoc(condObj, error); DebugOutPutBson(GetLogger(), conddoc, "UpdateDoc conddoc"); if (!conddoc) { LOG4CPLUS_WARN_FMT(GetLogger(), "condObj convert to bson failed(%s)", condObj.ToString().c_str()); retCode = ERR_REQ_MISS_PARAM; return retCode; } //更新的文档 bson_t * updatedoc = GetBsonDoc(updatedObj, error); DebugOutPutBson(GetLogger(), updatedoc); if (!updatedoc) { LOG4CPLUS_WARN_FMT(GetLogger(), "updatedObj convert to bson failed(%s)", updatedObj.ToString().c_str()); retCode = ERR_REQ_MISS_PARAM; return retCode; } //有则更新,否则不更新也不插入 if (!UpdateDoc(db, tb, conddoc, updatedoc)) { SAFE_DESTROY_BSON(conddoc); SAFE_DESTROY_BSON(updatedoc); retCode = ERR_OPERATOR_MONGO_ERROR; return retCode; } SAFE_DESTROY_BSON(conddoc); SAFE_DESTROY_BSON(updatedoc); return retCode; }
3.4更新插入请求
有则更新,无则插入int LbsProxySession::UpsertDoc(const char*db, const char* tb, const loss::CJsonObject &condObj, const loss::CJsonObject &updatedObj) { int retCode(ERR_OK); LOG4CPLUS_DEBUG_FMT(GetLogger(), "condObj json(%s),updatedObj json(%s)", condObj.ToString().c_str(), updatedObj.ToString().c_str()); //更新的条件 bson_t * conddoc = GetBsonDoc(condObj, error); DebugOutPutBson(GetLogger(), conddoc, "UpsertDoc conddoc"); if (!conddoc) { LOG4CPLUS_WARN_FMT(GetLogger(), "condObj convert to bson failed(%s)", condObj.ToString().c_str()); retCode = ERR_REQ_MISS_PARAM; return retCode; } //更新的文档 bson_t * updatedoc = GetBsonDoc(updatedObj, error); DebugOutPutBson(GetLogger(), updatedoc); if (!updatedoc) { LOG4CPLUS_WARN_FMT(GetLogger(), "updatedObj convert to bson failed(%s)", updatedObj.ToString().c_str()); retCode = ERR_REQ_MISS_PARAM; return retCode; } //有则更新,无则插入 if (!UpsertDoc(db, tb, conddoc, updatedoc)) { SAFE_DESTROY_BSON(conddoc); SAFE_DESTROY_BSON(updatedoc); retCode = ERR_OPERATOR_MONGO_ERROR; return retCode; } SAFE_DESTROY_BSON(conddoc); SAFE_DESTROY_BSON(updatedoc); return retCode; }
3.4删除请求
删除第一个满足条件的文档int LbsProxySession::DeleteDocOnce(const char*db, const char*tb, const loss::CJsonObject &condObj) { int retCode(ERR_OK); LOG4CPLUS_DEBUG_FMT(GetLogger(), "condObj json(%s)", condObj.ToString().c_str()); //删除的条件 bson_t * condDoc = GetBsonDoc(condObj, error); if (!condDoc) { LOG4CPLUS_WARN_FMT(GetLogger(), "condObj convert to bson failed(%s)", condObj.ToString().c_str()); retCode = ERR_REQ_MISS_PARAM; return retCode; } DebugOutPutBson(GetLogger(), condDoc, "DeleteDocOnce conddoc"); if (!DeleteDocOnce(db, tb, condDoc)) { SAFE_DESTROY_BSON(condDoc); retCode = ERR_OPERATOR_MONGO_ERROR; return retCode; } SAFE_DESTROY_BSON(condDoc); return retCode; }
阐述满足条件的所有的文档
int LbsProxySession::DeleteDocAll(const char*db, const char*tb, const loss::CJsonObject &condObj) { int retCode(ERR_OK); LOG4CPLUS_DEBUG_FMT(GetLogger(), "condObj json(%s),updatedObj json(%s)", condObj.ToString().c_str()); //删除的条件 bson_t * condDoc = GetBsonDoc(condObj, error); if (!condDoc) { LOG4CPLUS_WARN_FMT(GetLogger(), "condObj convert to bson failed(%s)", condObj.ToString().c_str()); retCode = ERR_REQ_MISS_PARAM; return retCode; } DebugOutPutBson(GetLogger(), condDoc, "DeleteDocAll conddoc"); if (!DeleteDocAll(db, tb, condDoc)) { SAFE_DESTROY_BSON(condDoc); retCode = ERR_OPERATOR_MONGO_ERROR; return retCode; } SAFE_DESTROY_BSON(condDoc); return retCode; }
3.4计数请求
int LbsProxySession::Count(const char*db, const char*tb, const loss::CJsonObject &condObj, long long &count) { int retCode(ERR_OK); LOG4CPLUS_DEBUG_FMT(GetLogger(), "condObj json(%s)", condObj.ToString().c_str()); //计算的条件 bson_t * condDoc = GetBsonDoc(condObj, error); if (!condDoc) { LOG4CPLUS_WARN_FMT(GetLogger(), "condObj convert to bson failed(%s)", condObj.ToString().c_str()); retCode = ERR_REQ_MISS_PARAM; return retCode; } DebugOutPutBson(GetLogger(), condDoc); if (!Count(db, tb, condDoc, count)) { SAFE_DESTROY_BSON(condDoc); retCode = ERR_OPERATOR_MONGO_ERROR; return retCode; } SAFE_DESTROY_BSON(condDoc); return retCode; }
3.5命令请求
int LbsProxySession::Command(const char*db, const char*tb, const loss::CJsonObject &commandObj, loss::CJsonObject &replyObj) { int retCode(ERR_OK); LOG4CPLUS_DEBUG_FMT(GetLogger(), "commandObj json(%s),updatedObj json(%s)", commandObj.ToString().c_str()); //执行的命令 bson_t * commandDoc = GetBsonDoc(commandObj, error); if (!commandDoc) { LOG4CPLUS_WARN_FMT(GetLogger(), "commandObj convert to bson failed(%s)", commandObj.ToString().c_str()); retCode = ERR_REQ_MISS_PARAM; return retCode; } DebugOutPutBson(GetLogger(), commandDoc, "Command commandDoc"); bson_t reply; if (!Command(db, tb, commandDoc, reply)) { SAFE_DESTROY_BSON(commandDoc); retCode = ERR_OPERATOR_MONGO_ERROR; return retCode; } char *bStr = bson_as_json(&reply, NULL); replyObj.Clear(); replyObj.Parse(bStr); bson_free(bStr); //调用的是free SAFE_DESTROY_BSON(commandDoc); return retCode; }
相关文章推荐
- spring-date-mongodb-1.0.0.M2 添加用户密码验证
- MongoDB创建索引(不锁库方法)
- Windows7下安装MongoDB
- 部署MongoDB Replica Set同时给数据库设置用户名密码
- 以windows Service的方式启动MongoDB
- python+mongodb==pymongo的源码安装
- Mongodb - TTL(time to live)特性
- MongoDB驱动之Linq操作
- 配置MongoDB的Windows服务
- MongoDB空间分配
- MongoDB操作:insert()
- MongoDB空间分配
- MongoDB操作:insert()
- MongoDB操作:flush()
- MongoDB操作:update()
- MongoDB下载及安装
- MongoDB存储数据
- MongoDB接口类函数
- MongoDB基本操作(增删改查)
- mongodb注册service启动失败(异常1053)