MongoDB C++ 数组的写操作

本文介绍了使用MongoDB C++驱动进行数组写操作的方法,包括插入简单数组元素和复杂对象数组,以及如何更新特定子数组元素的状态。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

MongoDB C++ 数组的写操作

经常会碰到这类问题,现在将前两年自己写过的代码总结一下,以后编程会方便很多。

Document中包含两个数组,一个简单点,每个元素都是string,一个复杂点,每个元素都是一个对象,有两个属性address和status.

> db.schedule.findOne({"_id" : ObjectId("51e930f92291307bb05a1a84")})
{
 "_id" : ObjectId("51e930f92291307bb05a1a84"),
 "direction" : 2,
 "messages" : [
  "m1",
  "m2",
  "m3"
 ],
 "receivers" : [
  {
   "address" : "000000000020",
   "status" : "waiting"
  },
  {
   "address" : "000000000018",
   "status" : "waiting"
  }
 ],
 "speed" : 3,
 "start_time" : "1374236921",
 "stay_time" : 1,
 "user_id" : ObjectId("518b7fc5117e87bce28f2444")
}

C++代码如下:

 

这个函数填充简单的数组,用到了BSONArrayBuilder. 注意其演示了insert方法的使用。

string AddScheduledMessage(ScheduledMessage const& m) {
  shared_ptr<mongo_session> mongo_session = mongo_session_factory::get_session();
  BSONObjBuilder data_builder;
  OID _id = OID::gen();
  data_builder.append("_id", _id);
  data_builder.append("user_id", mongo::OID(m.user_id));
  data_builder.append("start_time", m.start_time);
  data_builder.append("direction", m.direction);
  data_builder.append("speed", m.speed);
  data_builder.append("stay_time", m.stay_time);

  BSONArrayBuilder msgs_builder;
  size_t size = m.msgs.size();
  for (size_t i = 0; i < size; ++i) {
    msgs_builder.append(m.msgs[i]);
  }
  data_builder.append("messages", msgs_builder.arr());
  mongo_session->get().insert("db.schedule", data_builder.obj());
  return _id.str();
}

第二个函数添加了较复杂的数组,同时演示了update方法的使用。这个方法,假定receivers数组还不存在,采用$set命令进行设置。

void AssignScheduledMessages(ScheduledMessages & ms) {
  shared_ptr<mongo_session> mongo_session = mongo_session_factory::get_session();
  vector<shared_ptr<ScheduledMessage> >::iterator itor, last = ms.values.end();
  for (itor = ms.values.begin(); itor != last; ++itor) {
    shared_ptr<ScheduledMessage> m = *itor;
    BSONObjBuilder condition;
    condition.append("user_id", OID(m->user_id));
    condition.append("_id", OID(m->id));

    BSONArrayBuilder arr_builder;
    size_t size = m->receivers.size();
    for (size_t i = 0; i < size; ++i) {
      BSONObjBuilder rec;
      rec.append("address", m->receivers[i]->address);
      rec.append("status", m->receivers[i]->status);
      arr_builder.append(rec.obj());
    }

    BSONObjBuilder recs;
    recs.append("receivers", arr_builder.arr());

    BSONObjBuilder set;
    set.append("$set", recs.obj());
    
    mongo_session->get().update("db.schedule", mongo::Query(condition.obj()), set.obj());
  }
}

再复杂点。现在想修改一下address为00...20的那个元素的status="sending"。具体原理参考:

http://stackoverflow.com/questions/9247007/mongodb-update-the-specific-element-from-subarray

下面演示JavaScript代码:

db.schedule.update({"_id" : ObjectId("51e930f92291307bb05a1a84"), "receivers": {$elemMatch: {"address": "000000000020"}}}, {$set: {"receivers.$.status": "sending"}})
> db.schedule.findOne()
{
 "_id" : ObjectId("51e930f92291307bb05a1a84"),
 "direction" : 2,
 "messages" : [
  "m1",
  "m2",
  "m3"
 ],
 "receivers" : [
  {
   "address" : "000000000020",
   "status" : "sending"
  },
  {
   "address" : "000000000018",
   "status" : "waiting"
  }
 ],
 "speed" : 3,
 "start_time" : "1374236921",
 "stay_time" : 1,
 "user_id" : ObjectId("518b7fc5117e87bce28f2444")
}

$ 这是个占位符,表示第一个被找到的数组元素。文档:http://docs.mongodb.org/manual/core/update/#array

Name Description
$ Acts as a placeholder to update the first element that matches the query condition in an update.

C++代码来了:

void SaveScheduleMessageStatus(string const& message_id, string const& address, string const& status) {
  shared_ptr<MongoSession> mongo_session = MongoSessionFactory::GetSession();
  BSONObjBuilder condition;
  condition.append("_id", OID(message_id));

  BSONObjBuilder con1;
  con1.append("address", address);
    
  BSONObjBuilder con2;
  con2.append("$elemMatch", con1.obj());

  condition.append("receivers", con2.obj());

  BSONObjBuilder recs;
  recs.append("receivers.$.status", status);

  BSONObjBuilder set;
  set.append("$set", recs.obj());
    
  mongo_session->GetDBClientBase().update("db.schedule", mongo::Query(condition.obj()), set.obj());
}

推荐阅读:

MongoDB在PHP下的应用学习笔记 http://www.linuxidc.com/Linux/2013-07/87296.htm

MongoDB 入门指南、示例 http://www.linuxidc.com/Linux/2013-07/87106.htm

MongoDB基本知识和常用语法 http://www.linuxidc.com/Linux/2013-01/78251.htm

MongoDB入门必读(概念与实战并重) http://www.linuxidc.com/Linux/2013-07/87105.htm

linux
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值