Search code examples
mongo-cxx-driver

How to compare the "_id" in mongodb via mongocxx?


I'm going to build a server, and i have a list containing a struct("_id" is in it), now i want to compare the _id between the exist one in mongodb and the one in instruct.

I've finished the code, and when it comes to compiling, there are two same errors occured:

/usr/local/include/bsoncxx/v_noabi/bsoncxx/builder/stream/value_context.hpp:70:9: error: no matching function for call to ‘bsoncxx::v_noabi::builder::core::append(bsoncxx::v_noabi::document::element)’
         _core->append(std::forward<T>(t));
         ^

where the original code are:

 #include <iostream>
  2 #include <cstdint>
  3 #include <mongocxx/instance.hpp>
  4 #include <mongocxx/client.hpp>
  5 #include <mongocxx/options/find.hpp>
  6 #include <mongocxx/stdx.hpp>
  7 
  8 #include <bsoncxx/builder/basic/array.hpp>
  9 #include <bsoncxx/builder/stream/document.hpp>
 10 #include <bsoncxx/json.hpp>
 11 #include <bsoncxx/types.hpp>
 12 
 13 
 14 #include "DataStruct.h"
 15 using bsoncxx::types::value;
 16 using bsoncxx::builder::stream::finalize;
 17 using bsoncxx::builder::stream::document;
 18 using bsoncxx::builder::stream::open_document;
 19 using bsoncxx::builder::stream::close_document;
 20 
 21 int main(int, char**)
 22 {
 23         mongocxx::instance inst{};
 24         mongocxx::client conn{mongocxx::uri{"mongodb://172.16.103.100:27017"}};
 25 
 26 
 27         std::string m_Which_Attendance;
 28 
 29          LIST_Attendance lstInfo;
 30          LIST_Attendance::iterator iter;
 31 
 32 
 33          for(iter = lstInfo.begin(); iter != lstInfo.end(); ++iter)
 34              {
 35                   char datepick [10];
 36                   strcpy(datepick,(*iter).date.c_str());
 37                   int m_Mouth = (datepick[5]-48)*10+datepick[6]-48; //char to int -48
 38                   int m_Date = (datepick[8]-48)*10+datepick[9]-48;
 39 
 40                         if( m_Date <16 )  //find attendance_date <16 to  _1
 41                         {
 42                                 m_Which_Attendance  = "kg_attendance_"+std::to_string(m_Mouth)+"_1";
 43                         }
 44                         else
 45                         {
 46                                 m_Which_Attendance  = "kg_attendance_"+std::to_string(m_Mouth)+"_2";
 47 
 48                         }
 49 
 50 
 51 
 52 
  53                   auto db = conn["myattendance"];
 54                   auto cursor = db[m_Which_Attendance].find({});
 55                   {
 56                         for(auto&& doc : cursor)
 57                         {
 58                             if( (*iter)._id == doc["_id"].get_oid().value.to_string() )   //delete same id which was exist
 59                             {
 60 
 61                                  auto filter_builder = bsoncxx::builder::stream::document{};
 62                                  bsoncxx::document::value filter_value = filter_builder
 63                                  <<"_id" <<  doc["_id"] << bsoncxx::builder::stream::finalize;
 64                                  db[m_Which_Attendance].delete_one(filter_value.view());
 65 
 66 
 67                            }
 68 
 69                       /*     
 70                             auto builder = bsoncxx::builder::stream::document {};
 71                             bsoncxx::document::value doc_value = builder
 72                             << "_id" << (*iter)._id 
 73                             << "name" << (*iter).name
 74                             << "owner" <<  (*iter).owner_id 
 75                             << "owner_type" << (*iter).owner_type 
 76                             << "status" <<  (*iter).status 
 77                             << "date" <<  (*iter).date 
 78                             << "relationship" << (*iter).relationship 
 79                             << "guardian_id" << (*iter).guardian_id 
 80                             << "school_id" <<  (*iter).school_id 
 81                             << "dep_id" <<  (*iter).dep_id 
 82                             << "dep_code" <<  (*iter).dep_code 
 83                             << "grade_code" <<  (*iter).grade_code 
 84                             << "signin_time" <<  (*iter).signin_time 
 85                             << "signout_time" <<  (*iter).signout_time 
 86                             << "signin_score" <<  (*iter).signin_score 
 87                             << "signout_score" <<  (*iter).signout_score 
 88                             << "signin_image_name" <<  (*iter).signin_image_name 
 89                             << "signout_image_name" <<  (*iter).signout_image_name 
 90                             << bsoncxx::builder::stream::finalize;
 91                             
 92                            bsoncxx::stdx::optional<mongocxx::result::insert_one> result =
 93                              db[m_Which_Attendance].insert_one( std::move(doc_value) );
 94                         */
 95                         }
 96                   }
 97 
 98 
 99              }
100 
101 }

can someone help pls~


Solution

  • The compilation error is caused by doc["_id"] when you're building the document:

     62              bsoncxx::document::value filter_value = filter_builder
     63              <<"_id" <<  doc["_id"] << bsoncxx::builder::stream::finalize;
    

    doc["_id"] is a bsoncxx::v_noabi::document::element but you need to build it using a bsoncxx::oid since the _id is a MongoDB ObjectId type.

    With your current code, you can try with the following:

                auto filter_builder = bsoncxx::builder::stream::document{};
                bsoncxx::document::value filter_value = filter_builder
                    << "_id"
                    << bsoncxx::oid{ doc["_id"].get_oid().value.to_string() } // <- This is the change
                    << bsoncxx::builder::stream::finalize;
                db[m_Which_Attendance].delete_one(filter_value.view());
    

    But looking at what you want to do, it seems that the find_one_and_delete might work for you better.

    Instead of retrieving all documents (line 54) and looping on all docs trying to find the one with the matching _id, just perform the find_one_and_delete operation using the _id as shown above. Here's an example from mongocxx repository.