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 ) ) );
// 按照 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 );