问题
How to generate Mongodb documents recursively using mongocxx c++ driver? 1. I use mongocxx c++ driver v.3 and c++11. 2. Here is my main.cpp method, which parses hex string and generate mongocxx code like this: console:$ ./main dissect 0x160301012c01000128030340c70e243001b96d8c and the output:
<< "MainType" << bsoncxx::builder::stream::open_document
<< "TLSRecord" << bsoncxx::builder::stream::open_document
<< "type"<< "16"
<< "version"<< "0301"
<< "length"<< "012C"
<< "hsMsg" << bsoncxx::builder::stream::open_document
<< "type"<< "01"
<< "length"<< "000128"
<< "clientHello" << bsoncxx::builder::stream::open_document
<< "version"<< "0303"
<< "random"<< "40C70E243001B96D8C"
<< "session_id_length"<< ""
<< bsoncxx::builder::stream::close_document
<< bsoncxx::builder::stream::close_document
<< bsoncxx::builder::stream::close_document
After this I needed to push it in mongodb.
Call connection method from dissect method form main.cpp Call mongodb connection after hex string parsing
Create the mongodbConnection:
Call MongodbMapper to map generated code to db
Call GenerateDocument to generate it automatically Connect -> Mapp -> Generate -> Insert
And Here I got stacked, got error when try to compile it.
src/MongodbMapper.cpp:76:6: note: candidate function not viable: no known conversion from
'bsoncxx::v_noabi::builder::stream::key_context<bsoncxx::v_noabi::builder::stream::key_context<bsoncxx::v_noabi::builder::stream::closed_context> >' to
'bsoncxx::builder::stream::document &' for 3rd argument void generateDocument(DataUnit& node, int level, bsoncxx::builder::stream::document& doc) {
回答1:
It's hard to be sure without seeing the context of the segment you posted, but it looks like the issue you're running into is with the output type of the <<
operator on the stream builder. The stream builder is actually misnamed; it isn't a "stream" in the typical C++ sense of the word, as the output type of the <<
operator will sometime be different than the left-hand-side operand. In particular, whenever you use something like open_document
or close_document
, the type that expression outputs will be different than what the left-hand-side operand is. Because of this, you'll generally need to store the output of one of those expressions.
Because of the confusion that the stream builder often causes in cases like this, it's generally preferable to use the basic builder instead. While the basic builder's syntax is a little more verbose, it's much harder to make a subtle mistake with it, and when you do make a mistake, the compiler error messages are much easier to understand.
Here's how you would build up the same document with the basic builder:
#include <bsoncxx/builder/basic/document.hpp>
#include <bsoncxx/builder/basic/kvp.hpp>
#include <bsoncxx/builder/basic/sub_document.hpp>
using bsoncxx::builder::basic::kvp;
using bsoncxx::builder::basic::sub_document;
bsoncxx::builder::basic::document doc;
// Build the document
doc.append(kvp("MainType", [](sub_document sub_doc1) {
sub_doc1.append(kvp("TLSRecord", [](sub_document sub_doc2) {
sub_doc2.append(kvp("type", "16"),
kvp("version", "0301"),
kvp("length", "012C"),
kvp("hsMsg", [](sub_document sub_doc3) {
sub_doc3.append(kvp("type", "01"),
kvp("length", "000128"),
kvp("clientHello", [](sub_document sub_doc4) {
sub_doc4.append(
kvp("version", "0303"),
kvp("random", "40C70E243001B96D8C"),
kvp("session_id_length", ""));
}));
}));
}));
}));
// Get a view of the document being built and do something with it.
do_something_with_document_view(doc.view());
// Extract the document from the builder and do something with it.
do_something_with_owned_document(doc.extract());
bsoncxx::builder::basic::document::append
takes a arbitrary number of kvp
's (key-value pairs) and appends them to the builder. For basic types like strings, you can just pass the value as the second argument. To build up a subdocument, use a lambda as the second argument that takes a bsoncxx::builder::basic::sub_document
and then append to that subdocument builder in same the same way.
To get the document out from the builder, you can either use the view()
or extract()
methods. view()
returns a bsoncxx::document::view()
, which is an unowned view of the document; the builder needs to remain alive for the entire time the view is used. extract()
returns a bsoncxx::document::value, which is an owned value; when extract()
is called, the builder is reset back to the empty state.
来源:https://stackoverflow.com/questions/42952742/how-to-generate-mongodb-documents-recursively-using-mongocxx-c-driver