4

Say, I inserted the following document using the mongo command line or shell:

db.Users.insert( 
    { 
        "user info":{ 
            "user name" : "Joe", 
            "password" : "!@#%$%" ,
            "Facebook" : "aaa", 
            "Google" : "joe z"
        }
    }
)

Then this entry is logged into the database with a system created ID.

If I want to achieve the following command line which only returns the value of a specific filed (_id in this case), using the cxx driver how should I do it?

Here is the command line:

db.Users.find({"user info.user name": "Joe"}, {"_id":1})

I tried the following C++ code

 bsoncxx::builder::stream::document document{} ;
 document<<"user info.user name"<<"Joe"<<"_id"<<1;
 auto cursor = myCollection.find(document.view());

 for (auto && doc : cursor) {
    std::cout << bsoncxx::to_json(doc) << std::endl;
 }

It simply give me nothing.

If I set

document<<"user info.user name"<<"Joe"

Then it returns the entire JSON message for me.

Please let me know if you have any better ideas.

Joe
  • 841
  • 2
  • 10
  • 25
  • 1
    You are including the projection part in the query, which won't work. Provide a ```mongocxx::options::find``` object as the second argument to ```mongocxx::collection::find``` which has been configured by calling the ```mongocxx::options::find::projection``` method. – acm Aug 23 '16 at 12:53
  • Thanks for your reply, can you please show me some example or links? – Joe Aug 23 '16 at 13:07

1 Answers1

10

Here's an example:

#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["test"]["foo"];
  coll.drop();

  // Insert a test document
  auto joe = document{} << "user info" << open_document << "user name"
                        << "Joe" << close_document << finalize;    
  auto result = coll.insert_one(joe.view());
  std::cout << "Inserted " << result->inserted_id().get_oid().value.to_string()
            << std::endl;

  // Create the query filter
  auto filter = document{} << "user info.user name"
                           << "Joe" << finalize;

  // Create the find options with the projection
  mongocxx::options::find opts{};
  opts.projection(document{} << "_id" << 1 << finalize);


  // Execute find with options
  auto cursor = coll.find(filter.view(), opts);
  for (auto &&doc : cursor) {
    std::cout << bsoncxx::to_json(doc) << std::endl;
  }
}
xdg
  • 2,975
  • 19
  • 17
  • Thank you very much for your answer sir. I see that you are a software engineer from mongo db, is it possible that you can suggest mongo putting more examples to the cxx driver tutorial/documentation? – Joe Aug 23 '16 at 20:38
  • 1
    I found the "finalize" somewhat buggy. If I put finalize at the end, it returns everything. However, if I remove the finalize, it returns only "_id", which is the expected behavior. You might also want to use document.view() in opts.projection(). Anyway thanks a lot for your help. – Joe Aug 24 '16 at 03:07
  • Which "finalize" did you have problem with? I tested the code I posted and it worked as expected. (Admittedly, I tested it against the master branch.) – xdg Aug 26 '16 at 13:09
  • `bsoncxx::builder::stream::finalize`... well it doesn't matter, probably I used some wrong namespace or it's due to my env, or I did something wrong, etc. I don't wanna spend time debug this as long as my code is working without `finalize`. Thanks for your help :) – Joe Aug 26 '16 at 20:05