1. 程式人生 > >C++ 操作mongodb 的程式碼彙總

C++ 操作mongodb 的程式碼彙總

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 ) ) );

執行完上述幾行程式碼後, 資料庫集合中的資訊如下

每個文件多了 sexage 欄位

為所有文件增加成績資訊, 儲存在一個數組 "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 );