Search code examples
c++mongo-cxx-driver

specific field value in mongocxx


I want to have all the values of a specific field in my mongodb using mongocxx. I have 100 documents in my collection and each having a field "X1_position", the values of this field is float. I want to get all the 100 values of that field and want to store it into an array. I am using following code, but it is not working

  #include <iostream>

  #include <bsoncxx/builder/stream/document.hpp>
  #include <bsoncxx/json.hpp>

  #include <mongocxx/client.hpp>
  #include <mongocxx/options/find.hpp>
  #include <mongocxx/instance.hpp>
  #include <mongocxx/uri.hpp>

  using bsoncxx::builder::stream::document;
  using bsoncxx::builder::stream::open_document;
  using bsoncxx::builder::stream::close_document;
  using bsoncxx::builder::stream::finalize;

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

  auto coll = conn["my_data"]["exp1"];

  bsoncxx::builder::stream::document mydoc;
  mydoc << "X1_Position";
  mongocxx::cursor cursor = coll.find( mydoc.view() );
  for(auto &&doc : cursor) {
      std::cout << doc["X1_ActualPosition"].get_utf8().value << "\n";
   }

  }

It compiles fine but gives following error while running the executable file.

    ./testmongo
    terminate called after throwing an instance of 'bsoncxx::v_noabi::exception'
    what():  can't convert builder to a valid view: unmatched key
    Aborted (core dumped)

Please help me


Solution

  • I think that what you're after is projection. You don't need to filter since you said you want all docs, but you need to tell MongoDB which fields you want back:

    auto coll = conn["my_data"]["exp1"];
    
    bsoncxx::builder::stream::document mydoc;
    
    // Use projection to pick the field you want
    // _id must be explicitly removed since it is returned by default
    bsoncxx::builder::stream::document myprojection;
    myprojection << "X1_ActualPosition" << 1 << "_id" << 0;
    
    mongocxx::options::find opts{};
    opts.projection(myprojection.view());
        
    mongocxx::cursor cursor = coll.find(mydoc.view(), opts);
        
    for (auto &&doc : cursor) {
        std::cout << doc["X1_ActualPosition"].get_double() << std::endl;
    }
    

    The error you get is because you're trying to build the query passing a key without a value to filter the docs, I think it would be similar to execute the following in mongodb interpreter (which also crashes):

    db.exp1.find({"X1_ActualPosition"}) // ERROR: SyntaxError: missing : after property id