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.

0

1 Answer 1

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.

Sign up to request clarification or add additional context in comments.

3 Comments

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
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.
Is there a replacement for the .vals(ints) technique using the 3.0 and above drivers?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.