C++ | bsoncxx::builder::stream | How to $push arrays in an array

895 views
Skip to first unread message

Guillaume

unread,
Jul 22, 2017, 3:17:17 PM7/22/17
to mongodb-user
Hi.

Using MongoDB C++, I would like to update existing documents in order to append subarrays to an existing array "myArrays". We assume that "myArrays" has always at least one subarray present before the update.

The structure of my documents is:

{
 
"myArrays": [
     
[
       
1,
       
2,
       
3
     
]
 
]
}

Now, Lets assume that I have a 2D vector:

std::vector<std::vector<int>> arrays; // the first one contains { 4, 5, 6 } and the second one { 7, 8, 9 }

I would like to update a given document (selected by its _id) with bsoncxx::builder::stream in order to obtain this:

{
 
"myArrays": [
     
[
       
1,
       
2,
       
3
     
],
     
[
       
4,
       
5,
       
6
     
],
     
[
       
7,
       
8,
       
9
     
]
 
]
}

Obviously, I need to use the collection.update() method as well as $push (and probably $each) but so far I have failed to implement this function.

Could you please help me?

Thank you!

Isabella Siu

unread,
Jul 24, 2017, 6:13:28 PM7/24/17
to mongodb-user
Hi,

This is a example of how I implemented it:
#include <bsoncxx/builder/stream/array.hpp>
#include <bsoncxx/builder/stream/document.hpp>
#include <bsoncxx/builder/stream/helpers.hpp>
#include <mongocxx/client.hpp>
#include <mongocxx/instance.hpp>
#include <mongocxx/uri.hpp>

int main() {
  mongocxx::instance inst{};
  mongocxx::client conn{mongocxx::uri{}};

  auto db = conn["test"];

  std::vector<std::vector<int>> arrays;
  std::vector<int> v1;
  v1.push_back(4);
  v1.push_back(5);
  v1.push_back(6);
  arrays.push_back(v1);
  std::vector<int> v2;
  v2.push_back(7);
  v2.push_back(8);
  v2.push_back(9);
  arrays.push_back(v2);

  using bsoncxx::builder::stream::document;
  using bsoncxx::builder::stream::array;
  using bsoncxx::builder::stream::open_array;
  using bsoncxx::builder::stream::close_array;
  using bsoncxx::builder::stream::open_document;
  using bsoncxx::builder::stream::close_document;

  auto arr = array{};

  for (int i = 0; i < arrays.size(); i++) {
    arr << open_array;
    for (int j = 0; j < arrays[i].size(); j++) {
      arr << arrays[i][j];
    }
    arr << close_array;
  }

  document filter_builder, update_builder;
  filter_builder << "_id" << 1;
  update_builder << "$push" << open_document << "myArrays" << open_document
                 << "$each" << arr.view() << close_document << close_document;

  db["array_thing"].update_one(filter_builder.view(), update_builder.view());
}

I hope it helps!

Guillaume

unread,
Jul 25, 2017, 1:04:19 PM7/25/17
to mongodb-user
It seems to work!

Thank you very much Isabella.
Reply all
Reply to author
Forward
0 new messages