Search code examples
c++mongodbc++11mongo-cxx-driver

mongdb c++ driver compilation error for document{}


I am trying to use mongodb with latest c++ driver following this example as reference.

My code is as follows:

#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::open_array;
using bsoncxx::builder::stream::close_array;
using bsoncxx::builder::stream::finalize;

class MongoDBApiUtils {

  public :
    MongoDBApiUtils(){}
    static json validateDoc(const std::string& key ,const json& regInfo);
    static json validatePreRegistration(const json& regInfo);
    static bool checkUserExist(const json& regInfo);
    static bool checkUserBlackList(const json& regInfo);


    /* 
     * Retrieves a latest block from blockchain, based on the 
     * given query field.  It is assumed that the database is
     * indexed on the queryField, to avoid O(n) problem.
     **/
    static json getLatestBlock(
          const mongocxx::database& db, const std::string& filter) {
      auto cursor = db["ctlblocks"].find_one(document{} << filter << finalize);
    }

    /** Creates and adds a new block into the blockchain **/
    static json addBlock(json& current, const json& prev) {

    }

  private :

};

#endif

But I get compile errors, which I am unable to decipher. It gives error on the line, where I am trying to create a cursor, by calling the find_one method.

In file included from /Volumes/second/nvi/github/blockchain_db/src/Impl/mongo/src/mongo_db_api.cpp:3:
/Volumes/second/nvi/github/blockchain_db/src/Impl/mongo/src/mongo_db_api_utils.hpp:47:46: error: no viable conversion from 'typename std::enable_if<!util::is_functor<const finalize_type &, void (single_context)>::value, key_context<closed_context> >::type' (aka 'bsoncxx::v_noabi::builder::stream::key_context<bsoncxx::v_noabi::builder::stream::closed_context>') to 'bsoncxx::document::view_or_value' (aka 'view_or_value<document::view, document::value>')
      auto cursor = db["ctlblocks"].find_one(document{} << filter << finalize);
                                             ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/usr/local/include/bsoncxx/v_noabi/bsoncxx/view_or_value.hpp:60:20: note: candidate constructor not viable: no known conversion from 'typename std::enable_if<!util::is_functor<const finalize_type &, void (single_context)>::value, key_context<closed_context> >::type' (aka 'bsoncxx::v_noabi::builder::stream::key_context<bsoncxx::v_noabi::builder::stream::closed_context>') to 'bsoncxx::v_noabi::document::view' for 1st argument
    BSONCXX_INLINE view_or_value(View view) : _view{view} {
                   ^   
/usr/local/include/bsoncxx/v_noabi/bsoncxx/view_or_value.hpp:69:20: note: candidate constructor not viable: no known conversion from 'typename std::enable_if<!util::is_functor<const finalize_type &, void (single_context)>::value, key_context<closed_context> >::type' (aka 'bsoncxx::v_noabi::builder::stream::key_context<bsoncxx::v_noabi::builder::stream::closed_context>') to 'bsoncxx::v_noabi::document::value &&' for 1st argument
    BSONCXX_INLINE view_or_value(Value&& value) : _value(std::move(value)), _view(*_value) {
                   ^   
/usr/local/include/bsoncxx/v_noabi/bsoncxx/view_or_value.hpp:75:20: note: candidate constructor not viable: no known conversion from 'typename std::enable_if<!util::is_functor<const finalize_type &, void (single_context)>::value, key_context<closed_context> >::type' (aka 'bsoncxx::v_noabi::builder::stream::key_context<bsoncxx::v_noabi::builder::stream::closed_context>') to 'const bsoncxx::v_noabi::view_or_value<bsoncxx::v_noabi::document::view, bsoncxx::v_noabi::document::value> &' for 1st argument
    BSONCXX_INLINE view_or_value(const view_or_value& other)
                   ^   
/usr/local/include/bsoncxx/v_noabi/bsoncxx/view_or_value.hpp:93:20: note: candidate constructor not viable: no known conversion from 'typename std::enable_if<!util::is_functor<const finalize_type &, void (single_context)>::value, key_context<closed_context> >::type' (aka 'bsoncxx::v_noabi::builder::stream::key_context<bsoncxx::v_noabi::builder::stream::closed_context>') to 'bsoncxx::v_noabi::view_or_value<bsoncxx::v_noabi::document::view, bsoncxx::v_noabi::document::value> &&' for 1st argument
    BSONCXX_INLINE view_or_value(view_or_value&& other) noexcept

Any ideas how to go about solving this?


Solution

  • You aren't in the right stream context to pass finalize, since you have only provided one value to the stream. To use the stream builder, you pass a key, and then its value:

    auto result = document{} << k1 << v1 << k2 << v2 << ... kn << vn << finalize

    Gives you a result object holding a BSON object representing the JSON

    { 'k1' : v1, 'k2' : v2, ... 'kn' : vn }

    Your code has provided only something key like, so the document stream is not in an accepting state for finalize.

    If your entire filter is a JSON string, then just convert it to BSON with bsoncxx::from_json. Note also that the stream based document builders are more or less de-emphasized, due to exactly this sort of opportunity for confusion and misuse.

    You may get better mileage from the basic builders.