Watch keynotes and sessions from MongoDB.live, our virtual developer conference.

How to extract data from c++ driver cursor

I am trying to extract data from MongoDB using the C++ driver.

I am able to successfully run a find query and can print the json string to the terminal, however I cannot figure out how to extract the data from the cursor. Ideally I don’t want to convert the data to a json string, and then parse the string, as that sounds like an unnecessary round trip. (is that assumption true?)

Is there a way to directly access the column values from the cursor, without needing to create a json string.

My code is below:

   mongocxx::instance inst{};
    mongocxx::client conn{mongocxx::uri{}};
    auto collection = conn["simpleemdb"]["priceCurves"];
    auto cursor = collection.find({});
 
    for (auto&& doc : cursor) {

At this point i would like to extract the document values.
For example i have a field in this collection called “curve name”,

I would like to do something like

curvename[i] = doc.getField("curve name")

Is that possible, or what options do I have. Any help with this would be greatly appreciated.

Please note performance is a large concern, so the most efficient method would be appreciated.

Hi @arif_saeed,

The cursor iterates though document::view, so you can retrieve a document::element from the view using the operator[]() member of view. For example:

auto cursor = collection.find({});
for (auto&& doc : cursor) {
    bsoncxx::document::element curvename = doc["curveName"];
    std::cout << "curve name: " << curvename.get_utf8().value << std::endl;
}

Please note that by default MongoDB queries return all fields in matching documents. To limit the amount of data returned to the application you can specify projection to restrict fields to return. See Project Fields to Return from Query for more information. For example in C++ to project just curveName field:

mongocxx::options::find opts;
opts.projection(make_document(kvp("curveName", 1)));
auto cursor = collection.find({}, opts);

Looking at the example line that you would like to do, I assumed that you’re trying to retrieve curve names from the collection and store into an array. If so, you can try using aggregation pipeline. For example, to retrieve all curveName field values from the collection into an array with no duplicate:

#include <bsoncxx/builder/basic/kvp.hpp>
#include <bsoncxx/builder/basic/document.hpp>

using bsoncxx::builder::basic::make_document;
using bsoncxx::builder::basic::kvp;

mongocxx::pipeline p{};
p.group(make_document(
    kvp("_id", NULL),
    kvp("curveNames", make_document(kvp("$addToSet", "$curveName")))
));
auto cursor = collection.aggregate(p, mongocxx::options::aggregate{});

See also $push operator, which adds array field without removing duplicates.

Regards,
Wan.

1 Like