MongoDB
 sql >> Datenbank >  >> NoSQL >> MongoDB

Wie generiert man Mongodb-Dokumente rekursiv mit dem Mongocxx-C++-Treiber?

Es ist schwer, sicher zu sein, ohne den Kontext des von Ihnen geposteten Segments zu sehen, aber es sieht so aus, als ob das Problem, auf das Sie stoßen, mit dem Ausgabetyp von << zusammenhängt Operator auf dem Stream Builder. Der Stream Builder ist eigentlich falsch benannt; es ist kein "Stream" im typischen C++-Sinn des Wortes, da der Ausgabetyp von << Operator wird manchmal anders sein als der linke Operand. Insbesondere dann, wenn Sie so etwas wie open_document verwenden oder close_document , unterscheidet sich der Typ, den Ausdruck ausgibt, von dem des Operanden auf der linken Seite. Aus diesem Grund müssen Sie im Allgemeinen die Ausgabe eines dieser Ausdrücke speichern.

Aufgrund der Verwirrung, die der Stream-Builder in solchen Fällen oft verursacht, ist es im Allgemeinen vorzuziehen, stattdessen den Basis-Builder zu verwenden. Während die Syntax des grundlegenden Builders etwas ausführlicher ist, ist es viel schwieriger, einen subtilen Fehler damit zu machen, und wenn Sie einen Fehler machen, sind die Compiler-Fehlermeldungen viel einfacher zu verstehen.

So würden Sie dasselbe Dokument mit dem Basic Builder erstellen:

#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 nimmt eine beliebige Anzahl von kvp 's (Schlüssel-Wert-Paare) und hängt sie an den Builder an. Bei einfachen Typen wie Strings können Sie den Wert einfach als zweites Argument übergeben. Verwenden Sie zum Erstellen eines Unterdokuments ein Lambda als zweites Argument, das ein bsoncxx::builder::basic::sub_document akzeptiert und dann auf die gleiche Weise an diesen Subdocument Builder anhängen.

Um das Dokument aus dem Builder herauszuholen, können Sie entweder view() verwenden oder extract() Methoden. view() gibt ein bsoncxx::document::view() zurück , bei der es sich um eine unbesessene Ansicht des Dokuments handelt; Der Builder muss für die gesamte Zeit, in der die Ansicht verwendet wird, am Leben bleiben. extract() gibt einen bsoncxx::document::value zurück, der ein eigener Wert ist; wenn extract() aufgerufen wird, wird der Builder auf den leeren Zustand zurückgesetzt.