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



  • 1
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值