C++ 操作mongodb 的程式碼彙總
阿新 • • 發佈:2019-02-13
mongodb 是UTF8格式, 所以儲存中文的時候, 需要用下面這個函式將中文轉換為 UTF8 格式
bool MB_To_UTF8( const std::string& strIn, std::string& strOut ) { strOut.clear(); int nInputLen = MultiByteToWideChar( CP_ACP, 0, strIn.c_str(), strIn.length(), NULL, 0 ); wchar_t wszStr[ 100 ] = { 0 }; char szResult[ 100 ] = { 0 }; int nWstrLen = MultiByteToWideChar( CP_ACP, 0, strIn.c_str(), strIn.length(), wszStr, nInputLen ); if( nWstrLen != nInputLen ) { return false; } int nUTF8_Len = WideCharToMultiByte( CP_UTF8, 0, wszStr, nInputLen, NULL, 0, NULL, NULL ); if( nUTF8_Len <= 0 ) { return false; } nWstrLen = WideCharToMultiByte( CP_UTF8, 0, wszStr, nInputLen, szResult, nUTF8_Len, NULL, NULL ); if( nWstrLen != nUTF8_Len ) { return false; } strOut = szResult; return true; }
定義資料庫集合名稱和 mongodb 例項
std::string strCollection = "test.foo";
mongo::DBClientConnection oDB;
假設要把學生資訊儲存到集合 "test.foo" 中, 學生資訊包括學號, 名字, 入學年月日,用下面這個結構體來描述學生資訊
typedef struct tagStudengInfo { int nStudentID; char szName[ 50 ]; // 入學年月日份 int nDmission_year; int nDmission_mon; int nDmission_mday; }ST_STUDENT_INFO;
儲存到資料庫中的程式碼如下
void InputStudentInfo( const ST_STUDENT_INFO& stStudentInfo ) { mongo::BSONObjBuilder oBOJCharacter; oBOJCharacter.append( "student_id", stStudentInfo.nStudentID ); // 學號 std::string strName; MB_To_UTF8( stStudentInfo.szName, strName ); oBOJCharacter.append( "name", strName ); // 名字 struct tm tmDmissionTime; memset( (void*)&tmDmissionTime, 0, sizeof( tmDmissionTime ) ); tmDmissionTime.tm_year = stStudentInfo.nDmission_year - 1900; tmDmissionTime.tm_mon = stStudentInfo.nDmission_mon - 1; tmDmissionTime.tm_mday = stStudentInfo.nDmission_mday; time_t t_DmissionTime = mktime( &tmDmissionTime ); mongo::Date_t stDate( t_DmissionTime * 1000 ); oBOJCharacter.append( "admission_time", stDate ); // 入學年月日 try { oDB.insert( strCollection, oBOJCharacter.obj() ); std::string strDBError = oDB.getLastError(); if( !strDBError.empty() ) { std::cout << "mongodb error, err = " << strDBError.c_str() << std::endl; } // 對 "student_id" 欄位建立唯一索引 mongo::IndexSpec oIds; oIds.addKey( "student_id" ); oIds.unique( true ); oDB.createIndex( strCollection, oIds ); } catch ( const mongo::DBException &e ) { std::cout << "InputStudentInfo caught " << e.what() << std::endl; } }
然後執行下面的程式碼
void main()
{
mongo::client::initialize();
try
{
oDB.connect("localhost");
}
catch( const mongo::DBException &e )
{
std::cout << "caught " << e.what() << std::endl;
return;
}
// 入學年份都是 2005 年 11 月 1 日
ST_STUDENT_INFO stStudentInfo_1, stStudentInfo_2;
stStudentInfo_1.nStudentID = 1;
strcpy( stStudentInfo_1.szName, "我的老闆是笨蛋" );
stStudentInfo_1.nDmission_year = 2005;
stStudentInfo_1.nDmission_mon = 11;
stStudentInfo_1.nDmission_mday = 1;
stStudentInfo_2.nStudentID = 2;
strcpy( stStudentInfo_2.szName, "money" );
stStudentInfo_2.nDmission_year = 2005;
stStudentInfo_2.nDmission_mon = 11;
stStudentInfo_2.nDmission_mday = 1;
InputStudentInfo( stStudentInfo_1 );
InputStudentInfo( stStudentInfo_2 );
mongo::client::shutdown();
}
使用 mongoVUE 檢視資料庫集合中的資訊如下
接下來, 為集合中的每個文件增加性別和年齡欄位
mongo::BSONObjBuilder oBOJ;
oBOJ.append( "sex", 0 ); // 性別, 0 表示男, 1 表示女
oBOJ.append( "age", 18 ); // 年齡
oDB.update( strCollection, mongo::BSONObj(), BSON( "$set" << oBOJ.obj() ), false, true );
假設 "我的老闆是笨蛋", 性別是男, 年齡40, 需要修改 年齡值, 即 age 欄位為 40
// 因為 student_id 是唯一索引, 所以按照 student_id 進行查詢並更新 age 欄位
// "我的老闆是笨蛋" 的學號 "student_id" 值是 1
oDB.update( strCollection, mongo::Query( BSON( "student_id" << 1 ) ), BSON( "$set" << BSON( "age" << 40 ) ) );
假設 "money", 性別是女, 年齡18, 需要修改性別, 即 sex 欄位
// 按照 student_id 進行查詢並更新 sex 欄位
// "money" 的學號 "student_id" 值是 2
oDB.update( strCollection, mongo::Query( BSON( "student_id" << 2 ) ), BSON( "$set" << BSON( "sex" << 1 ) ) );
執行完上述幾行程式碼後, 資料庫集合中的資訊如下
每個文件多了 sex 和 age 欄位
為所有文件增加成績資訊, 儲存在一個數組 "transcripts" 中
mongo::BSONObjBuilder oBOJ_1;
mongo::BSONArrayBuilder arr_o;
for( int i = 0; i < 2; i++ )
{
// 陣列中的每個元素是一個子文件
mongo::BSONObjBuilder o;
o.append( "course_name", "name" ); // 表示課程名稱, 欄位型別是 String, 預設值是 "name"
o.append( "score", 0 ); // 表示分數, 欄位型別 Int32 預設值是 0
arr_o.append( o.obj() );
}
oBOJ_1.appendArray( "transcripts", arr_o.arr() ); //
oDB.update( strCollection, mongo::BSONObj(), BSON( "$set" << oBOJ_1.obj() ), false, true );
執行完上述幾行程式碼後, 資料庫集合中的資訊如下
假設陣列 "transcripts" 的第一個子文件表示語文成績, 第二個子文件表示數學成績, 需要把課程名稱 "course_name" 欄位的值分別修改為 "chinese" 和 “math”
這樣可以讓更直觀的表達出資訊
mongo::BSONObj obj_chinese = BSON( "$set" << BSON( "transcripts.0.course_name" << "chinese" ) ); // 課程名稱是 "chinese" 表示 語文成績
mongo::BSONObj obj_math = BSON( "$set" << BSON( "transcripts.1.course_name" << "math" ) ); // 課程名稱是 "math" 表示 數學成績
oDB.update( strCollection, mongo::BSONObj(), obj_chinese, false, true );
oDB.update( strCollection, mongo::BSONObj(), obj_math, false, true );
更新 "我的老闆是笨蛋" 語文成績 100 分, 數學 59 分; "money" 語文 80 分, 數學 100 分
oDB.update( strCollection, mongo::Query( BSON( "student_id" << 1 ) ), BSON( "$set" << BSON( "transcripts.0.score" << 100 << "transcripts.1.score" << 59 ) ) );
oDB.update( strCollection, mongo::Query( BSON( "student_id" << 2 ) ), BSON( "$set" << BSON( "transcripts.0.score" << 80 << "transcripts.1.score" << 100 ) ) );
執行完上述幾行程式碼後, 資料庫集合中的資訊如下對 transcripts 陣列擴容,增加英語成績的資訊
// 陣列擴容, 增加英語成績
mongo::BSONObj o = BSON( "$push" << BSON( "transcripts" << BSON( "course_name" << "English" << "score" << 80 ) ) );
oDB.update( strCollection, mongo::Query(), o, false, true );
// 增加表示年級的欄位
// 增加表示年級的欄位
mongo::BSONObjBuilder oBOJ_2;
oBOJ_2.append( "grade", 1 );
oDB.update( strCollection, mongo::Query(), BSON( "$set" << oBOJ_2.obj() ), false, true );