5

For example, if I do this in shell

> db.numbers.save( { name: "fibonacci", arr: [0, 1, 1, 2, 3, 5, 8, 13, 21] } )

Then i want to get arr in my c++ program.

After i got BSONObj i can get name with

std::string name = p.getStringField("name");

where p is a BSON object.

But what is the right way to get elements from array and save them into std::vector?

EDIT:

After some more research i found BSONElement doxygen documentation and made this.

std::vector<int> arr;
std::vector<BSONElement> v = p.getField("arr").Array();
for(std::vector<BSONElement>::iterator it = v.begin(); it != v.end(); ++it)
    arr.push_back(it->numberInt());

But im still not sure if it is the right way.

twid
  • 6,368
  • 4
  • 32
  • 50
Stals
  • 1,543
  • 4
  • 27
  • 52

1 Answers1

6

Two other ways:

// this way is easy but requires exact type match (no int64->int32 conversion)
std::vector<int> ints;
p.getObjectField("arr").vals(ints); // skips non int values
p.getObjectField("arr").Vals(ints); // asserts on non int values

or

// this way is more common and does the conversion between numeric types
vector<int> v;
BSONObjIterator fields (p.getObjectField("arr"));
while(fields.more()) {
    v.push_back(fields.next().numberInt());
}

//same as above but using BSONForEach macro
BSONForEach(e, p.getObjectField("arr")) {
    v.push_back(e.numberInt());
}

Alternatively, you could just leave the output as a vector<BSONElement> and use them directly, but then you will need to be sure that the BSONObj will outlive the vector.

mstearn
  • 4,156
  • 1
  • 19
  • 18
  • i would hope the first form is way better as the set of items to load become large, since the implementation has a chance to call `boost::vector<>::reserve()` with the final size of the vector – lurscher May 04 '12 at 16:40
  • Actually, it doesn't. Due to the way the BSON format is layed out, there is no way to know how many elements are in an object/array without iterating over it. If you look at the implementation of vals, you will see that it is almost identical to the second version. What differences there are, would be more likely to make it (slightly) slower in fact, but not enough to matter. – mstearn May 04 '12 at 16:55
  • 1
    Is there a replacement for the .vals(ints) technique using the 3.0 and above drivers? – jcairney Aug 07 '20 at 18:11