2. mongocxx
續上一篇,接著看一下mongocxx中的檔案有些什麼。
先看一下基本的增刪改查操作: 2.1 connect.cpp 資料庫的連結
參見之前的部落格。 2.2 create.cpp 構造文檔並插入
構造一個文檔,插入資料庫中的一個collection。關於builder::stream::document的使用見同系列部落格之(三)。
#include <bsoncxx/builder/stream/document.hpp>#include <bsoncxx/types.hpp>#include <mongocxx/client.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;int main(int, char**) { mongocxx::instance inst{}; mongocxx::client conn{mongocxx::uri{}}; auto db = conn["test"]; // TODO: fix dates // @begin: cpp-insert-a-document bsoncxx::document::value restaurant_doc = document{} << "address" << open_document << "street" << "2 Avenue" << "zipcode" << "10075" << "building" << "1480" << "coord" << open_array << -73.9557413 << 40.7720266 << close_array << close_document << "borough" << "Manhattan" << "cuisine" << "Italian" << "grades" << open_array << open_document << "date" << bsoncxx::types::b_date{std::chrono::milliseconds{12323}} << "grade" << "A" << "score" << 11 << close_document << open_document << "date" << bsoncxx::types::b_date{std::chrono::milliseconds{121212}} << "grade" << "B" << "score" << 17 << close_document << close_array << "name" << "Vella" << "restaurant_id" << "41704620" << finalize; // We choose to move in our document here, which transfers ownership to insert_one() auto res = db["restaurants"].insert_one(std::move(restaurant_doc)); // @end: cpp-insert-a-document}
在資料庫test中的restaurant”表”(collection)中插入一個檔案restaurant_doc:
{ "address" : { "street" :"2 Avenue", "zipcode" :"10075", "building" :"1480", "coord" :[-73.9557413,40.7720266], }, "borough" : "Manhattan", "cuisine" : "Italian", "grades" : [ { "date" : ***時間, “grade" : "A", "score" : 11 } { "date" : ***時間, ”grade" : "B", "score" : 17 } ] "name" : "Vella", "restaruant_id" : "41706420"}
2.3 update.cpp 找到一個合格文檔,修改/建立一個索引值對 嵌套修改/建立一個索引值對 修改多個檔案中的索引值對 找到一個合格文檔,替換文檔中的一部分內容
int main(int, char**) { mongocxx::instance inst{}; mongocxx::client conn{mongocxx::uri{}}; auto db = conn["test"]; // Update top-level fields in a single document. { // @begin: cpp-update-top-level-fields //找到有"name":"Juni"索引值對的文檔,使用\$set指定一個 //鍵"cuisine"(如果文檔中沒有將建立),將這個索引值對改 //成"cuisine":"American(New)",然後使用\$currentDate指定 //叫做"lastModified"的鍵,bool值true表示這個鍵對應的值使用 //Date的形式(見此系列(2)中的常用資料類型 //使用Unix的時間格式記錄下當前的時間。 bsoncxx::builder::stream::document filter_builder, update_builder; filter_builder << "name" << "Juni"; update_builder << "$set" << open_document << "cuisine" << "American (New)" << close_document << "$currentDate" << open_document << "lastModified" << true << close_document; db["restaurants"].update_one(filter_builder.view(), update_builder.view()); // @end: cpp-update-top-level-fields } // Update an embedded document in a single document. //找到restaurant_id是41156888的這家餐館的資訊,把地址資訊(文檔)裡面的street改成East 31st Street { // @begin: cpp-update-embedded-field bsoncxx::builder::stream::document filter_builder, update_builder; filter_builder << "restaurant_id" << "41156888"; update_builder << "$set" << open_document << "address.street" << "East 31st Street" << close_document; db["restaurants"].update_one(filter_builder.view(), update_builder.view()); // @end: cpp-update-embedded-field } // Update multiple documents. { // @begin: cpp-update-multiple-documents bsoncxx::builder::stream::document filter_builder, update_builder; filter_builder << "address.zipcode" << "10016" << "cuisine" << "Other"; update_builder << "$set" << open_document << "cuisine" << "Category To Be Determined" << close_document << "$currentDate" << open_document << "lastModified" << true << close_document; db["restaurants"].update_many(filter_builder.view(), update_builder.view()); // @end: cpp-update-multiple-documents } // Replace the contents of a single document. { // @begin: cpp-replace-document //找到含有filter_builder資訊的文檔,將其中的對應資訊替換成 //replace_builder的資訊 bsoncxx::builder::stream::document filter_builder, replace_builder; filter_builder << "restaurant_id" << "41704620"; replace_builder << "name" << "Vella 2" << "address" << open_document << "coord" << open_array << -73.9557413 << 40.7720266 << close_array << "building" << "1480" << "street" << "2 Avenue" << "zipcode" << "10075" << close_document; db["restaurants"].replace_one(filter_builder.view(), replace_builder.view()); // @end: cpp-replace-document }}
2.4 remove.cpp: 刪除一個或多個collection中合格document 刪除collection中所有的document 刪除collection
int main(int, char**) { mongocxx::instance inst{}; mongocxx::client conn{mongocxx::uri{}}; auto db = conn["test"]; // Remove all documents that match a condition. { // @begin: cpp-remove-matching-documents //刪除有"borough":"Manhattan"索引值對的document bsoncxx::builder::stream::document filter_builder; filter_builder << "borough" << "Manhattan"; db["restaurants"].delete_many(filter_builder.view()); // @end: cpp-remove-matching-documents } // Remove one document that matches a condition. { // @begin: cpp-remove-justone bsoncxx::builder::stream::document filter_builder; filter_builder << "borough" << "Queens"; db["restaurants"].delete_one(filter_builder.view()); // @end: cpp-remove-justone } // Remove all documents in a collection. { // @begin: cpp-remove-all-documents db["restaurants"].delete_many({}); // @end: cpp-remove-all-documents } // Drop a collection. { // @begin: cpp-drop-collection db["restaurants"].drop(); // @end: cpp-drop-collection }}
2.5 query.cpp: 查詢一個collection中所有的檔案 條件查詢含有某個索引值對的document 條件查詢含有某個索引值對(值為document,在document中繼續巢狀查詢) 條件查詢含有某個索引值對(值為array,在array中繼續巢狀查詢) 使用$gt(greater than),$lt(less than)進行條件查詢 多個條件查詢 相當於sql裡的and 滿足多個條件中至少一個條件查詢,相當於sql中的or] 對查詢結果進行排序
int main(int, char**) { mongocxx::instance inst{}; mongocxx::client conn{mongocxx::uri{}}; auto db = conn["test"]; // Query for all the documents in a collection. //查詢test資料庫的restaurants集合中的所有文檔 { // @begin: cpp-query-all auto cursor = db["restaurants"].find({}); for (auto&& doc : cursor) { std::cout << bsoncxx::to_json(doc) << std::endl; } // @end: cpp-query-all } // Query for equality on a top level field. //查詢restaurants集合中所有含"borough":"Manhattan"索引值對的文檔 { // @begin: cpp-query-top-level-field auto cursor = db["restaurants"].find(document{} << "borough" << "Manhattan" << finalize); for (auto&& doc : cursor) { std::cout << bsoncxx::to_json(doc) << std::endl; } // @end: cpp-query-top-level-field } // Query by a field in an embedded document. //巢狀查詢,查詢郵編為10075的餐館的文檔,address是文檔中嵌套的一個文檔,zipcode是address中的一個key,10075是zipcode對應的value. { // @begin: cpp-query-embedded-document bsoncxx::builder::stream::document filter_builder; filter_builder << "address.zipcode" << "10075"; auto cursor = db["restaurants"].find(filter_builder.view()); for (auto&& doc : cursor) { std::cout << bsoncxx::to_json(doc) << std::endl; } // @end: cpp-query-embedded-document } // Query by a field in an array. //grades鍵對應的值是一個array,裡面有兩個文檔,在這個數組中尋找grade鍵的值是B的文檔 { // @begin: cpp-query-field-in-array bsoncxx::builder::stream::document filter_builder; filter_builder << "grades.grade" << "B"; auto cursor = db["restaurants"].find(filter_builder.view()); for (auto&& doc : cursor) { std::cout << bsoncxx::to_json(doc) << std::endl; } // @end: cpp-query-field-in-array } // Query with the greater-than operator ($gt). //在grades對應的array中尋找score大於30的文檔 { // @begin: cpp-query-greater-than bsoncxx::builder::stream::document filter_builder; filter_builder << "grades.score" << open_document << "$gt" << 30 << close_document; auto cursor = db["restaurants"].find(filter_builder.view()); for (auto&& doc : cursor) { std::cout << bsoncxx::to_json(doc) << std::endl; } // @end: cpp-query-greater-than } // Query with the less-than operator ($lt). //$gt和$lt,分別是大於和小於 { // @begin: cpp-query-less-than bsoncxx::builder::stream::document filter_builder; filter_builder << "grades.score" << open_document << "$lt" << 10 << close_document; auto cursor = db["restaurants"].find(filter_builder.view()); for (auto&& doc : cursor) { std::cout << bsoncxx::to_json(doc) << std::endl; } // @end: cpp-query-less-than } // Query with a logical conjunction (AND) of query conditions. //filter_builder中有多個索引值對,預設是and的關係,相當於SQL語句中的and,表示查詢cuisine是Italian並且zipcode是10075的餐館的文檔 { // @begin: cpp-query-logical-and bsoncxx::builder::stream::document filter_builder; filter_builder << "cuisine" << "Italian" << "address.zipcode" << "10075"; auto cursor = db["restaurants"].find(filter_builder.view()); for (auto&& doc : cursor) { std::cout << bsoncxx::to_json(doc) << std::endl; } // @end: cpp-query-logical-and } // Query with a logical disjunction (OR) of query conditions. //$or表示或的關係注意這個地方open_array/close_array和open_document/close_document的使用 { // @begin: cpp-query-logical-or bsoncxx::builder::stream::document filter_builder; filter_builder << "$or" << open_array << open_document << "cuisine" << "Italian" << close_document << open_document << "address.zipcode" << "10075" << close_document << close_array; auto cursor = db["restaurants"].find(filter_builder.view()); for (auto&& doc : cursor) { std::cout << bsoncxx::to_json(doc) << std::endl; } // @end: cpp-query-logical-or } // Sort query results. //1和-1表示升序和降序(應該是) { // @begin: cpp-query-sort mongocxx::options::find opts; bsoncxx::builder::stream::document order_builder; order_builder << "borough" << 1 << "address.zipcode" << -1; opts.sort(order_builder.view()); auto cursor = db["restaurants"].find({}, opts); for (auto&& doc : cursor) { std::cout << bsoncxx::to_json(doc) << std::endl; } // @end: cpp-query-sort }}
2.6 get_values_from_documents.cpp
從資料庫的文檔中取資料,輸出到cout
using bsoncxx::builder::stream::document;using bsoncxx::builder::stream::close_array;using bsoncxx::builder::stream::finalize;using bsoncxx::builder::stream::open_array;using bsoncxx::type;// Document model, showing array with nested documents://// {// "_id" : ObjectId(...),// "messagelist" : [// {// "uid" : 413098706,// "status" : 2,// "msg": "..."// },// ...// ]// }// Construct a document in the format of 'messagelist'.bsoncxx::document::value new_message(int64_t uid, int32_t status, std::string msg) { document doc; return doc << "uid" << uid << "status" << status << "msg" << msg << finalize;}// Insert a document into the database.void insert_test_data(mongocxx::collection& coll) { document builder{}; //這種賦值方法注意一下 builder << "messagelist" << open_array << new_message(413098706, 3, "Lorem ipsum...") << new_message(413098707, 2, "Lorem ipsum...") << new_message(413098708, 1, "Lorem ipsum...") << close_array; bsoncxx::document::value doc = builder << finalize; // Normally, one should check the return value for success. coll.insert_one(doc.view());}// Iterate over contents of messagelist.遍曆messagelist數組中的所有內容void iterate_messagelist(const bsoncxx::document::element& ele) { // Check validity and type before trying to iterate. if (ele.type() == type::k_array) { bsoncxx::array::view subarray{ele.get_array().value}; for (const bsoncxx::array::element& msg : subarray) { // Check correct type before trying to access elements. // Only print out fields if they exist; don't report missing fields. if (msg.type() == type::k_document) { bsoncxx::document::view subdoc = msg.get_document().value; bsoncxx::document::element uid = subdoc["uid"];//使用[]訪問鍵 bsoncxx::document::element status = subdoc["status"]; bsoncxx::document::element msg = subdoc["msg"]; if (uid && uid.type() == type::k_int64) { std::cout << "uid: " << uid.get_int64().value << std::endl; } if (status && status.type() == type::k_int32) { std::