diff --git a/snooty.toml b/snooty.toml index 3f1c923b..24425718 100644 --- a/snooty.toml +++ b/snooty.toml @@ -9,8 +9,15 @@ intersphinx = [ toc_landing_pages = [ "/installation", - "/api-abi-versioning" - ] + "/api-abi-versioning", + "/get-started", + "/connect", + "/read", + "/write", + "/indexes", + "/security", + "/data-formats", +] sharedinclude_root = "https://raw.githubusercontent.com/10gen/docs-shared/main/" @@ -20,4 +27,8 @@ driver-long = "MongoDB C++ Driver" driver-short = "C++ driver" version = "3.10" full-version = "{+version+}.2" -api = "https://mongocxx.org/api/current" \ No newline at end of file +api = "https://mongocxx.org/api/current" +string-data-type = "``string``" +int-data-type = "``int``" +stable-api = "Stable API" +mdb-server = "MongoDB Server" diff --git a/source/aggregation.txt b/source/aggregation.txt new file mode 100644 index 00000000..4a76cf1b --- /dev/null +++ b/source/aggregation.txt @@ -0,0 +1,195 @@ +.. _cpp-aggregation: + +==================================== +Transform Your Data with Aggregation +==================================== + +.. facet:: + :name: genre + :values: reference + +.. meta:: + :keywords: code example, transform, computed, pipeline + :description: Learn how to use the C++ driver to perform aggregation operations. + +.. contents:: On this page + :local: + :backlinks: none + :depth: 2 + :class: singlecol + +.. TODO: + .. toctree:: + :titlesonly: + :maxdepth: 1 + + /aggregation/aggregation-tutorials + +Overview +-------- + +In this guide, you can learn how to use the {+driver-short+} to perform +**aggregation operations**. + +Aggregation operations process data in your MongoDB collections and +return computed results. The MongoDB Aggregation framework, which is +part of the Query API, is modeled on the concept of data processing +pipelines. Documents enter a pipeline that contains one or more stages, +and this pipeline transforms the documents into an aggregated result. + +An aggregation operation is similar to a car factory. A car factory has +an assembly line, which contains assembly stations with specialized +tools to do specific jobs, like drills and welders. Raw parts enter the +factory, and then the assembly line transforms and assembles them into a +finished product. + +The **aggregation pipeline** is the assembly line, **aggregation stages** are the +assembly stations, and **operator expressions** are the +specialized tools. + +Aggregation Versus Find Operations +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +You can use find operations to perform the following actions: + +- Select which documents to return +- Select which fields to return +- Sort the results + +You can use aggregation operations to perform the following actions: + +- Run find operations +- Rename fields +- Calculate fields +- Summarize data +- Group values + +Limitations +~~~~~~~~~~~ + +Keep the following limitations in mind when using aggregation operations: + +- Returned documents cannot violate the + :manual:`BSON document size limit ` + of 16 megabytes. +- Pipeline stages have a memory limit of 100 megabytes by default. You can exceed this + limit by setting the ``allow_disk_use`` field of a ``mongocxx::options::aggregate`` + instance to ``true``. + +.. important:: $graphLookup Exception + + The :manual:`$graphLookup + ` stage has a strict + memory limit of 100 megabytes and ignores the ``allow_disk_use`` field. + +.. _cpp-aggregation-example: + +Aggregation Example +------------------- + +.. note:: + + The examples in this guide use the ``restaurants`` collection in the ``sample_restaurants`` + database from the :atlas:`Atlas sample datasets `. To learn how to create a + free MongoDB Atlas cluster and load the sample datasets, see the :atlas:`Get Started with Atlas + ` guide. + +To perform an aggregation, pass a ``mongocxx::pipeline`` instance containing the aggregation +stages to the ``collection.aggregate()`` method. + +The following code example produces a count of the number of bakeries in each borough +of New York. To do so, it uses an aggregation pipeline that contains the following stages: + +- :manual:`$match ` stage to filter for documents + in which the ``cuisine`` field contains the value ``"Bakery"`` + +- :manual:`$group ` stage to group the matching + documents by the ``borough`` field, accumulating a count of documents for each distinct + value + +.. io-code-block:: + + .. input:: /includes/aggregation.cpp + :start-after: start-match-group + :end-before: end-match-group + :language: cpp + :dedent: + + .. output:: + + { "_id" : "Brooklyn", "count" : 173 } + { "_id" : "Queens", "count" : 204 } + { "_id" : "Bronx", "count" : 71 } + { "_id" : "Staten Island", "count" : 20 } + { "_id" : "Missing", "count" : 2 } + { "_id" : "Manhattan", "count" : 221 } + +Explain an Aggregation +~~~~~~~~~~~~~~~~~~~~~~ + +To view information about how MongoDB executes your operation, you can +instruct the MongoDB query planner to **explain** it. When MongoDB explains +an operation, it returns **execution plans** and performance statistics. +An execution plan is a potential way MongoDB can complete an operation. +When you instruct MongoDB to explain an operation, it returns both the +plan MongoDB executed and any rejected execution plans. + +To explain an aggregation operation, run the ``explain`` database command by specifying +the command in a BSON document and passing it as an argument to the ``run_command()`` +method. + +The following example instructs MongoDB to explain the aggregation operation from the +preceding :ref:`cpp-aggregation-example`: + +.. io-code-block:: + + .. input:: /includes/aggregation.cpp + :start-after: start-explain + :end-before: end-explain + :language: cpp + :dedent: + + .. output:: + + { "explainVersion" : "2", "queryPlanner" : { "namespace" : "sample_restaurants.restaurants", + "indexFilterSet" : false, "parsedQuery" : { "cuisine" : { "$eq" : "Bakery" } }, "queryHash": + "...", "planCacheKey" : "...", "optimizedPipeline" : true, "maxIndexedOrSolutionsReached": + false, "maxIndexedAndSolutionsReached" : false, "maxScansToExplodeReached" : false, + "winningPlan" : { ... } + ... } + + +Additional Information +---------------------- + +MongoDB Server Manual +~~~~~~~~~~~~~~~~~~~~~ + +To view a full list of expression operators, see :manual:`Aggregation +Operators. ` + +To learn about assembling an aggregation pipeline and view examples, see +:manual:`Aggregation Pipeline. ` + +To learn more about creating pipeline stages, see :manual:`Aggregation +Stages. ` + +To learn more about explaining MongoDB operations, see +:manual:`Explain Output ` and +:manual:`Query Plans. ` + +.. TODO: + Aggregation Tutorials + ~~~~~~~~~~~~~~~~~~~~~ + +.. To view step-by-step explanations of common aggregation tasks, see +.. :ref:`cpp-aggregation-tutorials-landing`. + +API Documentation +~~~~~~~~~~~~~~~~~ + +For more information about executing aggregation operations with the {+driver-short+}, +see the following API documentation: + +- `aggregate() <{+api+}/classmongocxx_1_1v__noabi_1_1collection.html#a480f6d0f9986d43b1d17d6ed8876941d>`__ +- `mongocxx::options::aggregate <{+api+}/classmongocxx_1_1v__noabi_1_1options_1_1aggregate.html>`__ diff --git a/source/compatibility.txt b/source/compatibility.txt new file mode 100644 index 00000000..b100d2f4 --- /dev/null +++ b/source/compatibility.txt @@ -0,0 +1,45 @@ +.. _cpp-compatibility-tables: + +============= +Compatibility +============= + +.. contents:: On this page + :local: + :backlinks: none + :depth: 2 + :class: singlecol + +.. facet:: + :name: genre + :values: reference + +.. meta:: + :keywords: backwards compatibility, versions, upgrade + +MongoDB Compatibility +--------------------- + +The following compatibility table specifies the recommended version or versions +of the {+driver-long+} for use with a specific version of MongoDB. + +The first column lists the driver version. + +.. sharedinclude:: dbx/lifecycle-schedule-callout.rst + +.. sharedinclude:: dbx/compatibility-table-legend.rst + +.. include:: /includes/mongodb-compatibility-table-cxx.rst + +Language Compatibility +---------------------- + +The following compatibility table specifies the recommended version of the +{+driver-long+} for use with a specific version of C++. + +The first column lists the driver version. + +.. include:: /includes/language-compatibility-table-cxx.rst + +For more information on how to read the compatibility tables, see our guide on +:ref:`MongoDB Compatibility Tables. ` \ No newline at end of file diff --git a/source/connect.txt b/source/connect.txt new file mode 100644 index 00000000..f1e0c18c --- /dev/null +++ b/source/connect.txt @@ -0,0 +1,275 @@ +.. _cpp-connect: + +================== +Connect to MongoDB +================== + +.. contents:: On this page + :local: + :backlinks: none + :depth: 2 + :class: singlecol + +.. facet:: + :name: genre + :values: reference + +.. meta:: + :description: Learn how to use the C++ driver to connect to MongoDB. + :keywords: client, ssl + +.. toctree:: + :titlesonly: + :maxdepth: 1 + + /connect/instance + /connect/client + /connect/connection-targets + /connect/connection-options + /connect/tls + /connect/network-compression + /connect/stable-api + +Overview +-------- + +This page contains code examples that show how to connect your C++ application +to MongoDB with various settings. + +.. tip:: + + To learn more about the connection options on this page, see the link + provided in each section. + +To use a connection example from this page, copy the code example into the +:ref:`sample application ` or your own application. +Be sure to replace all placeholders in the code examples, such as ````, with +the relevant values for your MongoDB deployment. + +.. _cpp-connect-sample: + +.. include:: /includes/usage-examples/sample-app-intro.rst + +.. literalinclude:: /includes/usage-examples/connect-sample-app.cpp + :language: cpp + :copyable: true + :linenos: + :emphasize-lines: 16-18 + +Connection +---------- + +Atlas +~~~~~ + +The following code shows how to connect to a MongoDB Atlas deployment: + +.. literalinclude:: /includes/usage-examples/connect-code-examples.cpp + :language: cpp + :dedent: + :start-after: start-atlas + :end-before: end-atlas + +To learn more about connecting to an Atlas deployment, see :ref:`cpp-connection-atlas` +in the Connection Targets guide. + +Local Deployment +~~~~~~~~~~~~~~~~ + +The following code shows how to connect to a local MongoDB deployment: + +.. literalinclude:: /includes/usage-examples/connect-code-examples.cpp + :language: cpp + :dedent: + :start-after: start-local + :end-before: end-local + +To learn more about connecting to a local deployment, see :ref:`cpp-connection-local` +in the Connection Targets guide. + +Replica Set +~~~~~~~~~~~ + +The following code shows how to connect to a replica set deployment: + +.. literalinclude:: /includes/usage-examples/connect-code-examples.cpp + :language: cpp + :dedent: + :start-after: start-replica-set + :end-before: end-replica-set + +To learn more about connecting to a replica set, see :ref:`cpp-connection-replica-set` +in the Connection Targets guide. + +Transport Layer Security (TLS) +------------------------------ + +Enable TLS +~~~~~~~~~~ + +The following code shows how to enable TLS for the connection to your +MongoDB instance: + +.. literalinclude:: /includes/usage-examples/connect-code-examples.cpp + :language: cpp + :dedent: + :start-after: start-enable-tls + :end-before: end-enable-tls + +To learn more about enabling TLS, see :ref:`cpp-enable-tls` in +the TLS configuration guide. + +Specify a Certificate Authority (CA) File +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The following code shows how to specify the path to your CA file +for the connection to your MongoDB instance: + +.. include:: /includes/connect/ca-file-tabs.rst + +To learn more about specifying a CA file, see :ref:`cpp-specify-ca-file` in +the TLS configuration guide. + +Disable OCSP Checks +~~~~~~~~~~~~~~~~~~~ + +The following code shows how to prevent the driver from contacting +the OCSP endpoint: + +.. literalinclude:: /includes/usage-examples/connect-code-examples.cpp + :language: cpp + :dedent: + :start-after: start-disable-ocsp + :end-before: end-disable-ocsp + +To learn more about disabling OCSP checks, see :ref:`cpp-disable-ocsp` in +the TLS configuration guide. + +Specify a Certificate Revocation List (CRL) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The following code shows how to instruct the driver to verify the server's +certificate against a CRL: + +.. literalinclude:: /includes/usage-examples/connect-code-examples.cpp + :language: cpp + :dedent: + :start-after: start-crl + :end-before: end-crl + +To learn more about specifying a CRL, see :ref:`cpp-crl` in the TLS +configuration guide. + +Present a Client Certificate +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The following code shows how to specify the client certificate that +the driver presents to your MongoDB deployment: + +.. include:: /includes/connect/client-cert-tabs.rst + +To learn more about specifying a client certificate, see :ref:`cpp-client-cert` in +the TLS configuration guide. + +Provide a Certificate Key File Password +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The following code shows how to specify the password for your +client certificate: + +.. include:: /includes/connect/key-file-password.rst + +To learn more about providing a key file password, see :ref:`cpp-key-file-password` in +the TLS configuration guide. + +Allow Insecure TLS +~~~~~~~~~~~~~~~~~~ + +The following code shows how to disable certificate verification: + +.. literalinclude:: /includes/usage-examples/connect-code-examples.cpp + :language: cpp + :dedent: + :start-after: start-insecure-tls + :end-before: end-insecure-tls + +To learn more about allowing insecure TLS, see :ref:`cpp-insecure-tls` in +the TLS configuration guide. + +Disable Certificate Validation +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The following code shows how to disable certificate validation: + +.. include:: /includes/connect/disable-cert-validation-tabs.rst + +To learn more about disabling certificate validation, see :ref:`cpp-insecure-tls` in +the TLS configuration guide. + +Disable Hostname Verification +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The following code shows how to disable hostname verification: + +.. literalinclude:: /includes/usage-examples/connect-code-examples.cpp + :language: cpp + :dedent: + :start-after: start-disable-hostname + :end-before: end-disable-hostname + +To learn more about disabling hostname verification, see :ref:`cpp-insecure-tls` in +the TLS configuration guide. + +Network Compression +------------------- + +Compression Algorithms +~~~~~~~~~~~~~~~~~~~~~~ + +The following code shows how to enable compression for the connection +to your MongoDB instance by specifying each compression algorithm: + +.. literalinclude:: /includes/usage-examples/connect-code-examples.cpp + :language: cpp + :dedent: + :start-after: start-compression-all + :end-before: end-compression-all + +To learn more about specifying compression algorithms, see +:ref:`cpp-enable-compression` in the Network Compression guide. + +zlib Compression Level +~~~~~~~~~~~~~~~~~~~~~~ + +The following code shows how to specify the ``zlib`` compression algorithm +and set its compression level: + +.. literalinclude:: /includes/usage-examples/connect-code-examples.cpp + :language: cpp + :dedent: + :start-after: start-compression-zlib + :end-before: end-compression-zlib + +To learn more about setting the zlib compression level, see +:ref:`cpp-enable-compression` in the Network Compression guide. + +{+stable-api+} +-------------- + +The following code shows how to enable the {+stable-api+} for the +connection to your MongoDB instance: + +.. literalinclude:: /includes/usage-examples/connect-code-examples.cpp + :language: cpp + :dedent: + :start-after: start-stable-api + :end-before: end-stable-api + +To learn more about the {+stable-api+}, see the :ref:`cpp-stable-api` guide. + +.. TODO: + Server Selection + ---------------- + Limit Server Execution Time + --------------------------- + diff --git a/source/connect/client.txt b/source/connect/client.txt new file mode 100644 index 00000000..23b82b9b --- /dev/null +++ b/source/connect/client.txt @@ -0,0 +1,113 @@ +.. _cpp-client: + +======================= +Create a MongoDB Client +======================= + +.. facet:: + :name: genre + :values: reference + +.. meta:: + :keywords: connection string, URI, server, Atlas, settings + +.. contents:: On this page + :local: + :backlinks: none + :depth: 2 + :class: singlecol + +Overview +-------- + +To connect to a MongoDB deployment, you need two things: + +- A **connection URI**, also known as a *connection string*, which tells the {+driver-short+} + which MongoDB deployment to connect to. +- A **mongocxx::client** object, which creates the connection to the MongoDB deployment + and lets you perform operations on it. + +You can also use either of these components to customize the way the {+driver-short+} behaves +while connected to MongoDB. + +This guide shows you how to create a connection string and use a ``mongocxx::client`` object +to connect to MongoDB. + +.. include:: /includes/assumes-instance.rst + +.. _cpp-connection-uri: + +Connection URI +-------------- + +A standard connection string includes the following components: + +.. list-table:: + :widths: 20 80 + :header-rows: 1 + + * - Component + - Description + + * - ``mongodb://`` + + - Required. A prefix that identifies this as a string in the + standard connection format. + + * - ``username:password`` + + - Optional. Authentication credentials. If you include these, the client + authenticates the user against the database specified in ``authSource``. + For more information about the ``authSource`` connection option, see + :ref:`cpp-auth`. + + * - ``host[:port]`` + + - Required. The host and optional port number where MongoDB is running. If you don't + include the port number, the driver uses the default port, ``27017``. + + * - ``/defaultauthdb`` + + - Optional. The authentication database to use if the + connection string includes ``username:password@`` + authentication credentials but not the ``authSource`` option. If you don't include + this component, the client authenticates the user against the ``admin`` database. + + * - ``?`` + + - Optional. A query string that specifies connection-specific + options as ``=`` pairs. See + :ref:`cpp-connection-options` for a full description of + these options. + +For more information about creating a connection string, see +:manual:`Connection Strings ` in the +MongoDB Server documentation. + +Create a ``mongocxx::client`` +----------------------------- + +To create a connection to MongoDB, construct an instance of the ``mongocxx::uri`` class, +passing the connection URI as a string to the constructor. Then, pass the instance of +the ``mongocxx::uri`` class to the ``mongocxx::client`` constructor. + +In the following example, the driver uses a sample connection URI to connect to a MongoDB +deployment on port ``27017`` of ``localhost``: + +.. literalinclude:: /includes/connect/client.cpp + :language: cpp + :copyable: true + +.. tip:: Reuse Your Client + + Because each ``mongocxx::client`` object represents a pool of connections to the + database, most applications require only a single instance of + ``mongocxx::client``, even across multiple requests. + +API Documentation +----------------- + +To learn more about creating a ``mongocxx::client`` object in {+driver-short+}, +see the following API documentation: + +- `mongocxx::client <{+api+}/classmongocxx_1_1v__noabi_1_1client.html>`__ \ No newline at end of file diff --git a/source/connect/connection-options.txt b/source/connect/connection-options.txt new file mode 100644 index 00000000..468b418a --- /dev/null +++ b/source/connect/connection-options.txt @@ -0,0 +1,335 @@ +.. _cpp-connection-options: + +========================== +Specify Connection Options +========================== + +.. contents:: On this page + :local: + :backlinks: none + :depth: 2 + :class: singlecol + +.. facet:: + :name: genre + :values: reference + +.. meta:: + :keywords: connection string, URI, server, Atlas, settings, configure + +Overview +-------- + +This page describes the MongoDB connection and authentication options +available in the {+driver-short+}. + +Set Connection Options +---------------------- + +You can configure your connection by specifying options in the connection URI or by +passing an instance of the ``mongocxx::options::client`` class as the ``client_options`` +parameter to the ``mongocxx::client`` constructor. + +.. note:: + + You can specify some connection options only in the connection URI, and others only + in an the ``client_options`` parameter. + You might need to combine these methods to specify all the options that you need. + +.. _cpp-connection-uri: + +Using the Connection URI +~~~~~~~~~~~~~~~~~~~~~~~~ + +When you construct a ``mongocxx::client`` object, you can pass in a ``mongocxx::uri`` +object that represents your connection URI. This connection URI can include +connection options as ``=`` pairs. In the following example, +the connection URI contains the ``tls`` option with a value of ``true`` and the +``tlsCertificateKeyFile`` option with a value of ``path/to/file.pem``: + +.. literalinclude:: /includes/connect/connection-options.cpp + :language: cpp + :copyable: true + :start-after: // start-connection-uri + :end-before: // end-connection-uri + :emphasize-lines: 8 + +.. _cpp-client-object: + +Using a ``mongocxx::options::client`` Object +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The ``mongocxx::client`` constructor includes a ``client_options`` parameter that +accepts an instance of the ``mongocxx::options::client`` class. You can specify +certain options in the ``client_options`` parameter instead of including them in your +connection URI. + +The following example shows how to use the ``client_options`` parameter +to set connection options: + +.. literalinclude:: /includes/connect/connection-options.cpp + :language: cpp + :copyable: true + :start-after: // start-client-options + :end-before: // end-client-options + :emphasize-lines: 8-12, 15 + +Read Connection Options +----------------------- + +After constructing a ``mongocxx::client`` object, you can read the values of certain +connection options by using properties of the +``mongocxx::uri`` object. + +The following example shows how to read the value of the ``tls`` connection options +by using the ``tls()`` property: + +.. literalinclude:: /includes/connect/connection-options.cpp + :language: cpp + :copyable: true + :start-after: // start-uri-object + :end-before: // end-uri-object + :emphasize-lines: 8, 10 + +The following sections show the corresponding ``mongocxx::uri`` property for +each connection option that supports it. + +Connection URI Options +---------------------- + +The following sections describe the connection options that you can set in the connection +URI passed to the {+driver-short+}. Each connection option links to +the {+mdb-server+} manual and to its corresponding ``mongocxx::uri`` +property, if supported. + +Replica Set Options +~~~~~~~~~~~~~~~~~~~ + +.. list-table:: + :header-rows: 1 + :stub-columns: 1 + + * - Connection URI Option + - ``mongocxx::uri`` Member + + * - :manual:`directConnection ` + - `direct_connection() `__ + + * - :manual:`replicaSet ` + - `replica_set() `__ + +Connection Options +~~~~~~~~~~~~~~~~~~ + +TLS Options +``````````` + +.. list-table:: + :header-rows: 1 + :stub-columns: 1 + + * - Connection URI Option + - ``mongocxx::uri`` Member + + * - :manual:`tls ` + - `tls() `__ + + * - :manual:`tlsCertificateKeyFile ` + - `tls_certificate_key_file() `__ + + * - :manual:`tlsCertificateKeyFilePassword ` + - `tls_certificate_key_file_password() `__ + + * - :manual:`tlsCAFile ` + - `tls_ca_file() `__ + + * - :manual:`tlsAllowInvalidCertificates ` + - `tls_allow_invalid_certificates() `__ + + * - :manual:`tlsAllowInvalidHostnames ` + - `tls_allow_invalid_hostnames() `__ + + * - :manual:`tlsInsecure ` + - `tls_insecure() `__ + + * - :manual:`tlsDisableCertificateRevocationCheck ` + - `tls_disable_certificate_revocation_check() `__ + + * - :manual:`tlsDisableOCSPEndpointCheck ` + - `tls_disable_ocsp_endpoint_check() `__ + +.. tip:: + + You can set most TLS options by using the ``client_options`` parameter. See the + `mongocxx::options::tls `__ + API documentation for more information. + +Timeout Options +``````````````` + +.. list-table:: + :header-rows: 1 + :stub-columns: 1 + + * - Connection URI Option + - ``mongocxx::uri`` Member + + * - :manual:`connectTimeoutMS ` + - `connect_timeout_ms() `__ + + * - :manual:`socketTimeoutMS ` + - `socket_timoeout_ms() `__ + +.. _cpp-compression-options: + +Compression Options +``````````````````` + +.. list-table:: + :header-rows: 1 + :stub-columns: 1 + + * - Connection URI Option + - ``mongocxx::uri`` Member + + * - :manual:`compressors ` + - `compressors() `__ + + * - :manual:`zlibCompressionLevel ` + - `zlib_compression_level() `__ + +Connection Pool Options +~~~~~~~~~~~~~~~~~~~~~~~ + +.. list-table:: + :header-rows: 1 + :stub-columns: 1 + + * - Connection URI Option + - ``mongocxx::uri`` Member + + * - :manual:`maxPoolSize ` + - `max_pool_size() `__ + + * - :manual:`waitQueueTimeoutMS ` + - `wait_queue_timeout_ms() `__ + +Write Concern Options +~~~~~~~~~~~~~~~~~~~~~ + +.. list-table:: + :header-rows: 1 + :stub-columns: 1 + + * - Connection URI Option + - ``mongocxx::uri`` Member + + * - :manual:`w ` + - `write_concern() `__ + + * - :manual:`wTimeoutMS ` + - N/A + + * - :manual:`journal ` + - N/A + +Read Concern Options +~~~~~~~~~~~~~~~~~~~~ + +.. list-table:: + :header-rows: 1 + :stub-columns: 1 + + * - Connection URI Option + - ``mongocxx::uri`` Member + + * - :manual:`readConcernLevel ` + - `read_concern() `__ + +Read Preference Options +~~~~~~~~~~~~~~~~~~~~~~~ + +.. list-table:: + :header-rows: 1 + :stub-columns: 1 + + * - Connection URI Option + - ``mongocxx::uri`` Member + + * - :manual:`readPreference ` + - `read_preference() `__ + + * - :manual:`maxStalenessSeconds ` + - N/A + + * - :manual:`readPreferenceTags ` + - N/A + +Authentication Options +~~~~~~~~~~~~~~~~~~~~~~ + +.. list-table:: + :header-rows: 1 + :stub-columns: 1 + + * - Connection URI Option + - ``mongocxx::uri`` Member + + * - :manual:`authMechanism ` + - `auth_mechanism() `__ + + * - :manual:`authMechanismProperties ` + - `auth_mechanism_properties() `__ + + * - :manual:`authSource ` + - `auth_source() `__ + +Server Selection and Discovery Options +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. list-table:: + :header-rows: 1 + :stub-columns: 1 + + * - Connection URI Option + - ``mongocxx::uri`` Member + + * - :manual:`localThresholdMS ` + - `local_threshold_ms() `__ + + * - :manual:`serverSelectionTimeoutMS ` + - `server_selection_timeout_ms() `__ + + * - :manual:`serverSelectionTryOnce ` + - `server_selection_try_once() `__ + + * - :manual:`heartbeatFrequencyMS ` + - `heartbeat_frequency_ms() `__ + + * - :manual:`socketCheckIntervalMS ` + - N/A + +Miscellaneous Configuration +~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. list-table:: + :header-rows: 1 + :stub-columns: 1 + + * - Connection URI Option + - ``mongocxx::uri`` Member + + * - :manual:`appName ` + - `appname() `__ + + * - :manual:`retryReads ` + - `retry_reads() `__ + + * - :manual:`retryWrites ` + - `retry_writes() `__ + + * - :manual:`loadBalanced ` + - N/A + + * - :manual:`srvMaxHosts ` + - `srv_max_hosts() `__ \ No newline at end of file diff --git a/source/connect/connection-targets.txt b/source/connect/connection-targets.txt new file mode 100644 index 00000000..f5c31b37 --- /dev/null +++ b/source/connect/connection-targets.txt @@ -0,0 +1,121 @@ +.. _cpp-connection-targets: + +========================== +Choose a Connection Target +========================== + +.. facet:: + :name: genre + :values: reference + +.. meta:: + :keywords: connection string, URI, server, settings, client, stable api + +.. contents:: On this page + :local: + :backlinks: none + :depth: 2 + :class: singlecol + +Overview +-------- + +In this guide, you can learn how to use a connection string and ``mongocxx::client`` object +to connect to different types of MongoDB deployments. + +.. _cpp-connection-atlas: + +Atlas +----- + +To connect to a MongoDB deployment on Atlas, include the following elements +in your connection string: + +- URI of your Atlas cluster +- MongoDB username +- MongoDB password + +Then, pass your connection string to the ``mongocxx::uri`` constructor, and use +the ``mongocxx::uri`` object to construct a ``mongocxx::client`` object. + +When you connect to Atlas, we recommend using the {+stable-api+} client option to avoid +breaking changes when Atlas upgrades to a new version of {+mdb-server+}. +To learn more about the {+stable-api+} feature, see the :ref:`{+stable-api+} page +`. + +The following code shows how to use the {+driver-short+} to connect to an Atlas cluster. +The code also uses the ``server_api_opts`` option to specify a {+stable-api+} version. + +.. literalinclude:: /includes/connect/atlas.cpp + :copyable: true + :language: cpp + +.. tip:: + + Follow the :atlas:`Atlas driver connection guide ` + to retrieve your connection string. + +.. _cpp-connection-local: + +Local Deployments +----------------- + +To connect to a local MongoDB deployment, use ``localhost`` as the hostname. By +default, the ``mongod`` process runs on port 27017, though you can customize this for +your deployment. + +The following code shows how to use the {+driver-short+} to connect to a local MongoDB +deployment: + +.. literalinclude:: /includes/connect/client.cpp + :language: cpp + :copyable: true + +.. _cpp-connection-replica-set: + +Replica Sets +------------ + +To connect to a replica set, specify the hostnames (or IP addresses) and +port numbers of the replica set members in your connection string. + +If you aren't able to provide a full list of hosts in the replica set, you can +specify one or more of the hosts in the replica set and instruct the {+driver-short+} to +perform automatic discovery to find the others. To instruct the driver to perform +automatic discovery, perform one of the following actions: + +- Specify the name of the replica set as the value of the ``replicaSet`` parameter. +- Specify ``false`` as the value of the ``directConnection`` parameter. +- Specify more than one host in the replica set. + +In the following example, the driver uses a sample connection URI to connect to the +MongoDB replica set ``sampleRS``, which is running on port ``27017`` of three different +hosts, including ``host1``: + +.. literalinclude:: /includes/connect/replica-set.cpp + :language: cpp + :copyable: true + +Initialization +~~~~~~~~~~~~~~ + +To initialize a replica set, you must connect directly to a single member. To do so, +set the ``directConnection`` connection +option to ``true`` in the connection string. The following code example shows how to +set this connection option: + +.. literalinclude:: /includes/connect/direct-connection.cpp + :language: cpp + :copyable: true + +API Documentation +----------------- + +To learn more about the types used on this page, +see the following API documentation: + +- `mongocxx::client <{+api+}/classmongocxx_1_1v__noabi_1_1client.html>`__ +- `mongocxx::uri <{+api+}/classmongocxx_1_1v__noabi_1_1uri.html>`__ +- `mongocxx::instance <{+api+}/classmongocxx_1_1v__noabi_1_1instance.html>`__ +- `mongocxx::options::client <{+api+}/classmongocxx_1_1v__noabi_1_1options_1_1client.html>`__ +- `mongocxx::options::server_api <{+api+}/classmongocxx_1_1v__noabi_1_1options_1_1server__api.html>`__ \ No newline at end of file diff --git a/source/connect/instance.txt b/source/connect/instance.txt new file mode 100644 index 00000000..6fdbeba7 --- /dev/null +++ b/source/connect/instance.txt @@ -0,0 +1,59 @@ +.. _cpp-instance: + +======================== +Create a Driver Instance +======================== + +.. facet:: + :name: genre + :values: reference + +.. meta:: + :keywords: start, connect, dependencies + +.. contents:: On this page + :local: + :backlinks: none + :depth: 2 + :class: singlecol + +Overview +-------- + +To use the {+driver-short+}, you must first create an instance of the ``mongocxx::instance`` +class. This instance performs the following functions in your application: + +- Initializes and shuts down the {+driver-short+} +- Initializes driver dependencies +- Ensures the driver functions correctly +- Manages the lifetimes of resources that + are shared among ``mongocxx::client`` objects, such as the connection pool + and BSON library + +This guide shows you how to create a ``mongocxx::instance`` object. + +Create a ``mongocxx::instance`` +------------------------------- + +To create a ``mongocxx::instance`` object, include the +``mongocxx/instance.hpp`` header file in your application. Then, +construct an instance of ``mongocxx::instance`` at the start of your application, +as shown in the following example: + +.. literalinclude:: /includes/connect/instance.cpp + :language: cpp + :copyable: true + +.. important:: + + You must create a ``mongocxx::instance`` object before you use the + {+driver-short+}, and this object must remain + alive for as long as any other MongoDB objects are in scope. + +API Documentation +----------------- + +To learn more about the ``mongocxx::instance`` class in the {+driver-short+}, +see the following API documentation: + +- `mongocxx::instance <{+api+}/classmongocxx_1_1v__noabi_1_1instance.html>`__ \ No newline at end of file diff --git a/source/connect/network-compression.txt b/source/connect/network-compression.txt new file mode 100644 index 00000000..85a0b1ef --- /dev/null +++ b/source/connect/network-compression.txt @@ -0,0 +1,86 @@ +.. _cpp-network-compression: + +======================== +Compress Network Traffic +======================== + +.. contents:: On this page + :local: + :backlinks: none + :depth: 2 + :class: singlecol + +.. facet:: + :name: genre + :values: reference + +.. meta:: + :keywords: zlib, zstandard, zstd, snappy + +Overview +-------- + +The {+driver-short+} provides a connection option to compress messages, which reduces the +amount of data passed over the network between MongoDB and your application. + +The {+driver-short+} supports the following compression algorithms: + +1. `Snappy `__: Available in MongoDB 3.6 and later. + +2. `Zlib `__: Available in MongoDB 3.6 and later. + +3. `Zstandard `__: Available in MongoDB 4.2 and later. + +If you don't specify a compression algorithm, the driver doesn't compress your +network traffic. If you specify multiple compression algorithms, the driver selects the +first one in the list supported by your MongoDB instance. + +.. _cpp-enable-compression: + +Specify Compression Algorithms +------------------------------ + +To enable compression for the connection to your MongoDB instance, include the +``compressors`` connection option in your URI and specify the compression algorithms you +want to use. The following code shows how to specify the ``snappy``, ``zstd``, and +``zlib`` algorithms, in that order: + +.. literalinclude:: /includes/connect/network-compression.cpp + :language: cpp + :copyable: true + :emphasize-lines: 8 + :start-after: // start-all-compression + :end-before: // end-all-compression + +Set the zlib Compression Level +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +If you specify ``zlib`` as one of your compression algorithms, you can also use the +``zlibCompressionLevel`` option to specify a compression level. This option accepts +an integer value between ``-1`` and ``9``: + +- **-1:** *(Default).* zlib uses its default compression level (usually ``6``). +- **0:** No compression. +- **1:** Fastest speed but lowest compression. +- **9:** Best compression but slowest speed. + +The following code example specifies the ``zlib`` compression algorithm and a value of +``1`` for the ``zlibCompressionLevel`` option: + +.. literalinclude:: /includes/connect/network-compression.cpp + :language: cpp + :copyable: true + :emphasize-lines: 8 + :start-after: // start-zlib-compression + :end-before: // end-zlib-compression + +API Documentation +----------------- + +To learn more about the types and options used on this page, +see the following API documentation: + +- `mongocxx::instance <{+api+}/classmongocxx_1_1v__noabi_1_1instance.html>`__ +- `mongocxx::client <{+api+}/classmongocxx_1_1v__noabi_1_1client.html>`__ +- `mongocxx::uri <{+api+}/classmongocxx_1_1v__noabi_1_1uri.html>`__ +- :ref:`` \ No newline at end of file diff --git a/source/connect/stable-api.txt b/source/connect/stable-api.txt new file mode 100644 index 00000000..ff72abb9 --- /dev/null +++ b/source/connect/stable-api.txt @@ -0,0 +1,119 @@ +.. _cpp-stable-api: + +============== +{+stable-api+} +============== + +.. contents:: On this page + :local: + :backlinks: none + :depth: 2 + :class: singlecol + +.. facet:: + :name: genre + :values: reference + +.. meta:: + :keywords: compatible, backwards, upgrade + +.. note:: + + The {+stable-api+} feature requires {+mdb-server+} 5.0 or later. + +Overview +-------- + +In this guide, you can learn how to specify **{+stable-api+}** compatibility when +connecting to a MongoDB deployment. + +The {+stable-api+} feature forces the server to run operations with behaviors compatible +with the API version you specify. When you update either your driver or server, +the API version changes, which can change the way these operations behave. +Using the {+stable-api+} ensures consistent responses from the server and +provides long-term API stability for your application. + +The following sections describe how you can enable and customize {+stable-api+} for +your MongoDB client. For more information about the {+stable-api+}, including a list of +the commands it supports, see :manual:`Stable API ` in the +{+mdb-server+} manual. + +Enable the {+stable-api+} +------------------------- + +To enable the {+stable-api+}, perform the following steps: + +1. Construct a ``mongocxx::options::server_api`` object and specify a {+stable-api+} + version. You must use a {+stable-api+} version defined in the + ``mongocxx::options::server_api::version`` enum. Currently, the driver supports only + version 1 (``k_version_1``). +#. Construct a ``mongocxx::options::client`` object. Set the ``server_api_opts`` field + of this object to the ``server_api`` object you created in the previous step. +#. Construct a ``mongocxx::client`` object, passing in your ``mongocxx::uri`` object + and the ``mongocxx::options::client`` object you created in the previous step. + +The following code example shows how to specify {+stable-api+} version 1: + +.. literalinclude:: /includes/connect/stable-api.cpp + :language: cpp + :copyable: true + :start-after: // start-specify-v1 + :end-before: // end-specify-v1 + :emphasize-lines: 10-13 + +.. note:: + + After you create a ``mongocxx::client`` instance with + a specified API version, all commands you run with the client use the specified + version. If you need to run commands using more than one version of the + {+stable-api+}, create a new ``mongocxx::client`` instance. + +.. _stable-api-options: + +Configure the {+stable-api+} +------------------------ + +The following table describes the properties of the ``server_api_options`` class. You can use +these properties to customize the behavior of the {+stable-api+}. + +.. list-table:: + :header-rows: 1 + :stub-columns: 1 + :widths: 25,75 + + * - Option Name + - Description + + * - strict + - | **Optional**. When ``true``, if you call a command that isn't part of + the declared API version, the driver raises an exception. + | + | Default: ``false`` + + * - deprecation_errors + - | **Optional**. When ``true``, if you call a command that is deprecated in the + declared API version, the driver raises an exception. + | + | Default: ``false`` + +The following code example shows how you can use these parameters when constructing a +``ServerApi`` object: + +.. literalinclude:: /includes/connect/stable-api.cpp + :language: cpp + :copyable: true + :start-after: // start-stable-api-options + :end-before: // end-stable-api-options + :emphasize-lines: 10-12 + +API Documentation +----------------- + +For more information about using the {+stable-api+} with the {+driver-short+}, see the +following API documentation: + +- `mongocxx::client <{+api+}/classmongocxx_1_1v__noabi_1_1client.html>`__ +- `mongocxx::uri <{+api+}/classmongocxx_1_1v__noabi_1_1uri.html>`__ +- `mongocxx::instance <{+api+}/classmongocxx_1_1v__noabi_1_1instance.html>`__ +- `mongocxx::options::client <{+api+}/classmongocxx_1_1v__noabi_1_1options_1_1client.html>`__ +- `mongocxx::options::server_api <{+api+}/classmongocxx_1_1v__noabi_1_1options_1_1server__api.html>`__ \ No newline at end of file diff --git a/source/connect/tls.txt b/source/connect/tls.txt new file mode 100644 index 00000000..6c820b2e --- /dev/null +++ b/source/connect/tls.txt @@ -0,0 +1,268 @@ +.. _cpp-tls: + +======================================== +Configure Transport Layer Security (TLS) +======================================== + +.. contents:: On this page + :local: + :backlinks: none + :depth: 2 + :class: singlecol + +.. facet:: + :name: genre + :values: reference + +.. meta:: + :keywords: security, authentication, transport layer security, encrypt + +Overview +-------- + +In this guide, you can learn how to use the :wikipedia:`TLS ` +protocol to secure your connection to a MongoDB deployment. + +When you enable TLS for a connection, the {+driver-short+} performs the following actions: + +- Uses TLS to connect to the MongoDB deployment +- Verifies the deployment's certificate +- Ensures that the certificate certifies the deployment + +To learn how to configure your MongoDB deployment for TLS, see the +:manual:`TLS configuration guide ` in the +{+mdb-server+} manual. + +.. note:: + + This page assumes prior knowledge of TLS/SSL and access to valid certificates. + A full description of TLS/SSL, PKI (Public Key Infrastructure) certificates, and + Certificate Authorities (CAs) is beyond the scope of this documentation. + +.. tip:: + + The C++ driver delegates most TLS behavior to the MongoDB C Driver. + For information about how the C driver handles TLS, including configuration steps + and expected behavior, see + `Configuring TLS `__ + in the C driver Documentation. + +.. _cpp-enable-tls: + +Enable TLS +---------- + +To enable TLS for the connection to your MongoDB instance, set the ``tls`` connection +option to ``true`` in your connection string, as shown in the following example: + +.. code-block:: cpp + + mongocxx::uri uri("mongodb://:/?tls=true"); + +.. tip:: + + If your connection string includes the ``+srv`` modification, which specifies the + SRV connection format, TLS is enabled on your connection by default. + + To learn more about the SRV connection format, see + :manual:`SRV Connection Format ` + in the {+mdb-server+} documentation. + +.. _cpp-specify-ca-file: + +Specify a CA File +------------------ + +During the TLS handshake, the MongoDB deployment presents a certificate key file to your +application to establish its identity. Usually, a deployment's certificate has been +signed by a well-known CA, and your application relies on this CA to validate the certificate. + +During testing, however, you might want to act as your own CA. +In this case, you must instruct the {+driver-short+} to +use your CA certificates instead of ones signed by another CA. + +To do so, specify the path to a ``.pem`` file containing the root certificate chain. +You can do this in two ways: by setting a property on a ``mongocxx::options::tls`` object, +or by using the ``tlsCAFile`` parameter in your connection string. + +.. include:: /includes/connect/ca-file-tabs.rst + +.. _cpp-specify-ca-directory: + +Specify a CA Directory +~~~~~~~~~~~~~~~~~~~~~~ + +If you are using OpenSSL or LibreSSL (``libtls``) for TLS support, you can also instruct +the {+driver-short+} to search for a CA file within a directory. The driver searches this +directory if it doesn't find a CA file at the path specified in the ``tlsCAFile`` or +``pem_file`` option. + +The following code example shows how to use the ``ca_dir`` option to specify the +directory that the driver should search: + +.. literalinclude:: /includes/connect/ca-dir.cpp + :language: cpp + :copyable: true + +.. tip:: + + This option corresponds to the OpenSSL + `SSL_CTX_load_verify_locations `__ + parameter and + the LibreSSL `tls_config_set_ca_path `__ + parameter. + +.. _cpp-certificate-revocation: + +Check Certificate Revocation +---------------------------- + +When an X.509 certificate is no longer trustworthy—for example, if its private key +has been compromised—the CA revokes the certificate. The {+driver-short+} includes two ways +to check whether a server's certificate has been revoked. + +.. _cpp-disable-ocsp: + +OCSP +~~~~ + +The Online Certificate Status Protocol (OCSP) process varies depending on the version of +{+mdb-server+} you're connecting to: + +- **MongoDB v4.4 or later:** The server staples a + time-stamped OCSP response to its certificate. The {+driver-short+} validates the certificate + against the OCSP response. If the CA has revoked the certificate, or if the OCSP response + is otherwise invalid, the TLS handshake fails. +- **MongoDB v4.3 or earlier:** The server supplies an OCSP endpoint, which the {+driver-short+} + contacts directly. The {+driver-short+} then validates the certificate against the OCSP + response. If the CA hasn't revoked the certificate, the TLS handshake continues, even if + the OCSP response is invalid or malformed. + +To stop the {+driver-short+} from contacting the OCSP endpoint, +set the ``tlsDisableOCSPEndpointCheck`` connection option to ``true`` in your +connection string, as shown in the following code example: + +.. code-block:: cpp + + mongocxx::uri uri("mongodb://:/?tls=true&tlsDisableOCSPEndpointCheck=true"); + +.. _cpp-crl: + +Certificate Revocation List +~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Instead of using OCSP, you can instruct the {+driver-short+} to check the server's certificate +against a Certificate Revocation List (CRL) published by the CA. + +The following code example shows how to use the ``crl_file`` option to specify the +path to specify the path to a ``.pem`` file from the CA: + +.. literalinclude:: /includes/connect/crl-file.cpp + :language: cpp + :copyable: true + +.. tip:: + + You can specify a CRL file in either the ``.pem`` or ``.der`` format. + +.. _cpp-client-cert: + +Present a Client Certificate +---------------------------- + +Some MongoDB deployments require every connecting application to present a client certificate +that proves its identity. To specify the client certificate for the {+driver-short+} to +present, specify the file path of the ``.pem`` file that +contains your certificate and private key. + +You can do this in two ways: by setting a property on a ``mongocxx::options::tls`` object, +or by using the ``tlsCertificateKeyFile`` parameter in your connection string. + +.. include:: /includes/connect/client-cert-tabs.rst + +.. important:: + + Your client certificate and private key must be in the same ``.pem`` file. If they + are stored in different files, you must concatenate them. The following example + shows how to concatenate a key file and a certificate file into a third file called + ``combined.pem`` on a Unix system: + + .. code-block:: sh + + $ cat key.pem cert.pem > combined.pem + +.. _cpp-key-file-password: + +Provide a Key Password +~~~~~~~~~~~~~~~~~~~~~~ + +If the private key in your certificate file is encrypted, you must provide the password. +You can do this in two ways: by setting a property on a ``mongocxx::options::tls`` object, +or by using the ``tlsCertificateKeyFilePassword`` parameter in your connection string. + +.. include:: /includes/connect/key-file-password.rst + +.. _cpp-insecure-tls: + +Allow Insecure TLS +------------------ + +When TLS is enabled, the {+driver-short+} automatically verifies the certificate that +the server presents. When testing your code, you can disable this verification. +This is known as *insecure TLS.* + +When insecure TLS is enabled, the driver requires only that the server present an +X.509 certificate. The driver accepts a certificate even if any of the following are +true: + +- The hostname of the server and the subject name (or subject alternative name) + on the certificate don't match. +- The certificate is expired or not yet valid. +- The certificate doesn't have a trusted root certificate in the chain. +- The certificate purpose isn't valid for server identification. + +.. note:: + + Even when insecure TLS is enabled, communication between the client and server + is encrypted with TLS. + +To enable insecure TLS, set the ``tlsInsecure`` connection +option to ``true`` in your connection string, as shown in the following code example: + +.. code-block:: cpp + + mongocxx::uri uri("mongodb://:/?tls=true&tlsInsecure=true"); + +To disable only certificate validation, set the ``tlsAllowInvalidCertificates`` option to +``true``, and set the ``tlsInsecure`` option to ``false`` (or omit it): + +.. include:: /includes/connect/disable-cert-validation-tabs.rst + +To disable only hostname verification, set the ``tlsAllowInvalidHostnames`` option to +``true``, and set the ``tlsInsecure`` option to ``false`` (or omit it): + +.. code-block:: cpp + + mongocxx::uri uri("mongodb://:/?tls=true&tlsAllowInvalidHostnames=true"); + +.. warning:: Don't Use in Production + + Always set the ``tlsInsecure``, ``tlsAllowInvalidCertificates``, and + ``tlsAllowInvalidHostnames`` options to ``false`` in production. + + Setting any of these options to ``true`` in a production environment makes + your application insecure and potentially + vulnerable to expired certificates and to foreign processes posing + as valid client instances. + +API Documentation +----------------- + +To learn more about configuring TLS for the {+driver-short+}, +see the following API documentation: + +- `mongocxx::client <{+api+}/classmongocxx_1_1v__noabi_1_1client.html>`__ +- `mongocxx::uri <{+api+}/classmongocxx_1_1v__noabi_1_1uri.html>`__ +- `mongocxx::instance <{+api+}/classmongocxx_1_1v__noabi_1_1instance.html>`__ +- `mongocxx::options::client <{+api+}/classmongocxx_1_1v__noabi_1_1options_1_1client.html>`__ +- `mongocxx::options::tls <{+api+}/classmongocxx_1_1v__noabi_1_1options_1_1tls.html>`__ \ No newline at end of file diff --git a/source/contributing.txt b/source/contributing.txt deleted file mode 100644 index 420ab8cd..00000000 --- a/source/contributing.txt +++ /dev/null @@ -1,170 +0,0 @@ -.. _cpp-contributing: - -======================= -Contribution Guidelines -======================= - -.. contents:: On this page - :local: - :backlinks: none - :depth: 1 - :class: singlecol - -.. facet:: - :name: genre - :values: reference - -Code Style -~~~~~~~~~~~ - -When contributing code, in addition to following the `C++ Core Guidelines -`__, please follow the same `design -guidelines `__ -and `style guidelines -`__ as `mongodb/mongo -`__. Additions and exceptions are listed -below. For anything that isn't explicitly covered here, default to the `Google -C++ Style Guide `__. -Running `clang-format `__ with our -configuration file, `mongo-cxx-driver/.clang-format -`__, will -help ensure your code conforms to the above standards. - -Commit Messages -~~~~~~~~~~~~~~~ - -If a pull-request addresses a JIRA ticket, for a single-commit PR, prefix -the subject line with the ticket ID. (For a multi-commit PR, we will add -the ID later when we squash or merge it.) - -.. code-block:: none - - CXX-883 Add commit message conventions to CONTRIBUTING.md - -Capitalize subject lines and don't use a trailing period. Keep the subject -at most 70 characters long. Use active voice! Imagine this preamble to get -your phrasing right: - -.. code-block:: none - - If applied, this commit will... [your subject line] - -See Chris Beams' -`How to write a git commit message `__ -for more good guidelines to follow. - -Lifecycle Methods -~~~~~~~~~~~~~~~~~ - -- default-or-argument-bearing 'user' constructors -- declaration-or-deletion-of-copy-constructor -- declaration-or-deletion-of-move-constructor -- declaration-or-deletion-of-copy-assignment-operator -- declaration-or-deletion-of-move-assignment-operator -- declaration-of-dtor - -Headers -~~~~~~~ - -Public headers must have a ".hpp" suffix. Private headers must have a ".hh" -suffix. - -General structure: - -- License -- Include Guard (``#pragma once``) -- Header Prelude -- System Headers ```` (alphabetical order) -- Driver Headers ```` (alphabetical order) -- Open Namespace mongocxx -- ``inline namespace v_noabi {`` -- Code -- ``} // namespace v_noabi`` -- Close Namespace mongocxx -- Header Postlude - -Example: - -.. code-block:: cpp - - // Copyright 2018-present MongoDB Inc. - // - // Licensed under the Apache License, Version 2.0 (the "License"); - // you may not use this file except in compliance with the License. - // You may obtain a copy of the License at - // - // http://www.apache.org/licenses/LICENSE-2.0 - // - // Unless required by applicable law or agreed to in writing, software - // distributed under the License is distributed on an "AS IS" BASIS, - // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - // See the License for the specific language governing permissions and - // limitations under the License. - - #pragma once - - #include - - #include - - #include - - namespace mongocxx { - inline namespace v_noabi { - - // Declarations - - // Inline Implementations - - } // namespace v_noabi - } // namespace mongocxx - - #include - -Class Declarations -~~~~~~~~~~~~~~~~~~ - -Guidelines: - -- Blank line at beginning and end of class declaration -- Public section up top / private at bottom -- Lifecycle methods first (see rules above) -- Private Member Ordering - - - Friendships - - Private Constructors - - Private Methods - - Private Variables - -Example: - -.. code-block:: cpp - - class foo { - - public: - foo(); - - foo(foo&& other) noexcept; - foo& operator=(foo&& other) noexcept; - - ~foo(); - - private: - friend baz; - - class MONGOCXX_PRIVATE impl; - std::unique_ptr _impl; - - }; - -Inlines -~~~~~~~ - -- Define outside of class declaration -- Specify inline keyword in declaration and definition (for clarity) - -Relational Operators -~~~~~~~~~~~~~~~~~~~~ - -- Prefer to use free functions diff --git a/source/data-formats.txt b/source/data-formats.txt new file mode 100644 index 00000000..5c562a38 --- /dev/null +++ b/source/data-formats.txt @@ -0,0 +1,35 @@ +.. _cpp-data-formats: + +======================== +Specialized Data Formats +======================== + +.. contents:: On this page + :local: + :backlinks: none + :depth: 1 + :class: singlecol + +.. facet:: + :name: genre + :values: reference + +.. meta:: + :keywords: store, timeseries + +.. toctree:: + :titlesonly: + :maxdepth: 1 + + /data-formats/time-series + +Overview +-------- + +You can use several types of specialized data formats in your {+driver-short+} +application. To learn how to work with these data formats, see the following +sections: + +- Learn how to store and interact with time series data in the :ref:`cpp-time-series` guide. + +.. TODO: link to BSON data guide \ No newline at end of file diff --git a/source/data-formats/time-series.txt b/source/data-formats/time-series.txt new file mode 100644 index 00000000..84b7c4c5 --- /dev/null +++ b/source/data-formats/time-series.txt @@ -0,0 +1,174 @@ +.. _cpp-time-series: + +================ +Time Series Data +================ + +.. default-domain:: mongodb + +.. contents:: On this page + :local: + :backlinks: none + :depth: 1 + :class: singlecol + +Overview +-------- + +In this guide, you can learn how to use the {+driver-short+} to store +and interact with **time series data**. + +Time series data is composed of the following components: + +- Measured quantity +- Timestamp for the measurement +- Metadata that describes the measurement + +The following table describes sample situations for which you could store time +series data: + +.. list-table:: + :widths: 33, 33, 33 + :header-rows: 1 + :stub-columns: 1 + + * - Situation + - Measured Quantity + - Metadata + + * - Recording monthly sales by industry + - Revenue in USD + - Company, country + + * - Tracking weather changes + - Precipitation level + - Location, sensor type + + * - Recording fluctuations in housing prices + - Monthly rent price + - Location, currency + +.. _cpp-time-series-create: + +Create a Time Series Collection +------------------------------- + +.. important:: Server Version for Time Series Collections + + To create and interact with time series collections, you must be + connected to a deployment running {+mdb-server+} 5.0 or later. + +You can create a time series collection to store time series data. +To create a time series collection, perform the following actions: + +1. Create a BSON document that specifies the properties of + your time series collection. + +#. Call the ``create_collection()`` method and pass the collection + name and the time series BSON document as arguments. + +.. _cpp-time-series-create-example: + +Example +~~~~~~~ + +This example creates the ``sept2023`` time series collection in the +``precipitation`` database with the following configuration: + +- ``timeField`` is set to ``"timestamp"`` +- ``metaField`` is set to ``"location"`` +- ``granularity`` is set to ``"minutes"`` + +.. literalinclude:: /includes/data-formats/time-series.cpp + :start-after: start-create-ts + :end-before: end-create-ts + :language: php + :dedent: + +To verify that you successfully created the time series collection, run +the ``list_collections()`` method on the database and print the results: + +.. io-code-block:: + :copyable: true + + .. input:: /includes/data-formats/time-series.cpp + :start-after: start-list-colls + :end-before: end-list-colls + :language: php + :dedent: + + .. output:: + :language: console + :visible: false + + { "name" : "sept2023", "type" : "timeseries", "options" : { "timeseries" : + { "timeField" : "timestamp", "metaField" : "location", "granularity" : + "minutes", "bucketMaxSpanSeconds" : 86400 } }, "info" : ... } + +.. _cpp-time-series-store: + +Store Time Series Data +---------------------- + +You can insert data into a time series collection by using the ``insert_one()`` +or ``insert_many()`` methods and specifying the measurement, timestamp, and metadata +in each inserted document. + +.. tip:: + + To learn more about inserting documents into a collection, see the :ref:`cpp-write-insert` + guide. + +Example +~~~~~~~ + +This example inserts New York City precipitation data into the ``sept2023`` +time series collection created in the :ref:`Create a Time Series Collection example +`. Each document contains the following fields: + +- ``precipitation_mm``, which stores precipitation measurements in millimeters +- ``location``, which stores location metadata +- ``timestamp``, which stores the time of the measurement collection + +.. literalinclude:: /includes/data-formats/time-series.cpp + :start-after: start-insert-ts + :end-before: end-insert-ts + :language: php + :dedent: + +.. _cpp-time-series-query: + +Query Time Series Data +---------------------- + +You can use the same syntax and conventions to query data stored in a time +series collection as you use when performing read or aggregation operations on +other collections. To find more information about these operations, see +the :ref:`Additional Information ` section. + +.. _cpp-time-series-addtl-info: + +Additional Information +---------------------- + +To learn more about the concepts mentioned in this guide, see the +following Server manual entries: + +- :manual:`Time Series ` +- :manual:`Create and Query a Time Series Collection ` +- :manual:`Set Granularity for Time Series Data ` + +To learn more about performing read operations, see :ref:`cpp-read`. + +To learn more about performing aggregation operations, see the :ref:`cpp-aggregation` +guide. + +API Documentation +~~~~~~~~~~~~~~~~~ + +To learn more about the methods mentioned in this guide, see the following +API documentation: + +- `create_collection() <{+api+}/classmongocxx_1_1v__noabi_1_1database.html#a8989a894e021e87d704288a8d2522069>`__ +- `list_collections() <{+api+}/classmongocxx_1_1v__noabi_1_1database.html#aacef87f0bc585c536ce0dfae67cfefe8>`__ +- `insert_many() <{+api+}/classmongocxx_1_1v__noabi_1_1collection.html#a533e1d929fb71a6e85303769f3175275>`__ diff --git a/source/get-started.txt b/source/get-started.txt new file mode 100644 index 00000000..d3799cf3 --- /dev/null +++ b/source/get-started.txt @@ -0,0 +1,48 @@ +.. _cpp-get-started: + +=============================== +Get Started with the C++ Driver +=============================== + +.. contents:: On this page + :local: + :backlinks: none + :depth: 2 + :class: singlecol + +.. facet:: + :name: genre + :values: tutorial + +.. meta:: + :description: Learn how to create an app to connect to MongoDB deployment by using the C++ driver. + :keywords: quick start, tutorial, basics + +.. toctree:: + + /get-started/download-and-install/ + /get-started/create-a-deployment/ + /get-started/create-a-connection-string/ + /get-started/connect-to-mongodb/ + /get-started/next-steps/ + +Overview +-------- + +The {+driver-long+} is a C++ package that you can use to connect to MongoDB and +interact with data stored in your deployment. This guide shows you how to create an +application that uses the {+driver-short+} to connect to a MongoDB cluster hosted on +MongoDB Atlas and query data in your cluster. + +.. tip:: + + MongoDB Atlas is a fully managed cloud database service that hosts your MongoDB + deployments. You can create your own free (no credit card required) MongoDB Atlas + deployment by following the steps in this guide. + +Follow this guide to connect a sample C++ application to a MongoDB Atlas +deployment. If you prefer to connect to MongoDB using a different driver or +programming language, see our :driver:`list of official drivers <>`. + +.. button:: Next: Download and Install + :uri: /get-started/download-and-install/ \ No newline at end of file diff --git a/source/get-started/connect-to-mongodb.txt b/source/get-started/connect-to-mongodb.txt new file mode 100644 index 00000000..5f90ac02 --- /dev/null +++ b/source/get-started/connect-to-mongodb.txt @@ -0,0 +1,97 @@ +.. _cpp-quick-start-connect-to-mongodb: + +================== +Connect to MongoDB +================== + +.. facet:: + :name: genre + :values: tutorial + +.. meta:: + :keywords: test connection, runnable, code example + +.. procedure:: + :style: connected + + .. step:: Create a project directory + + From your root directory, run the following command in your shell to create a directory called + ``cpp-quickstart`` for this project: + + .. code-block:: bash + + mkdir cpp-quickstart + + Run the following commands to create a ``quickstart.cpp`` application file in the ``cpp-quickstart`` + directory: + + .. code-block:: bash + + cd cpp-quickstart + touch quickstart.cpp + + .. step:: Create your {+driver-short+} application + + Copy and paste the following code into the ``quickstart.cpp`` file, which queries + the ``movies`` collection in the ``sample_mflix`` database: + + .. literalinclude:: /includes/get-started/quickstart.cpp + + .. step:: Assign the connection string + + Replace the ```` placeholder with the + connection string that you copied from the :ref:`cpp-quick-start-connection-string` + step of this guide. + + .. step:: Run your C++ application + + In your shell, run the following commands to compile and run this application: + + .. code-block:: none + + c++ --std=c++17 quickstart.cpp $(pkg-config --cflags --libs libmongocxx) -o ./app.out + ./app.out + + .. tip:: + + MacOS users might see the following error after running the preceding commands: + + .. code-block:: bash + :copyable: false + + dyld[54430]: Library not loaded: @rpath/libmongocxx._noabi.dylib + + To resolve this error, use the ``-Wl,-rpath`` linker option to set the ``@rpath``, as shown + in the following code: + + .. code-block:: none + + c++ --std=c++17 quickstart.cpp -Wl,-rpath,/usr/local/lib/ $(pkg-config --cflags --libs libmongocxx) -o ./app.out + ./app.out + + The command line output contains details about the retrieved movie + document: + + .. code-block:: none + :copyable: false + + { "_id" : { "$oid" : "573a1399f29313caabceeb20" }, + "plot" : "Two imprisoned men bond over a number of years, finding solace + and eventual redemption through acts of common decency.", + ... + "title" : "The Shawshank Redemption", + ... + + If you encounter an error or see no output, ensure that you specified the + proper connection string in the ``quickstart.cpp`` file and that you loaded the + sample data. + +After you complete these steps, you have a working application that +uses the driver to connect to your MongoDB deployment, runs a query on +the sample data, and prints out the result. + +.. include:: /includes/get-started/troubleshoot.rst + +.. button:: Next Steps + :uri: /get-started/next-steps/ diff --git a/source/get-started/create-a-connection-string.txt b/source/get-started/create-a-connection-string.txt new file mode 100644 index 00000000..9833ddc0 --- /dev/null +++ b/source/get-started/create-a-connection-string.txt @@ -0,0 +1,64 @@ +.. _cpp-quick-start-connection-string: + +========================== +Create a Connection String +========================== + +You can connect to your MongoDB deployment by providing a +**connection URI**, also called a *connection string*, which +instructs the driver on how to connect to a MongoDB deployment +and how to behave while connected. + +The connection string includes the hostname or IP address and +port of your deployment, the authentication mechanism, user credentials +when applicable, and connection options. + +.. TODO: link to instructions on connecting to local deployment in Connection guide + +.. procedure:: + :style: connected + + .. step:: Find your MongoDB Atlas Connection String + + To retrieve your connection string for the deployment that + you created in the :ref:`previous step `, + log in to your Atlas account and navigate to the + :guilabel:`Database` section and click the :guilabel:`Connect` button + for your new deployment. + + .. figure:: /includes/figures/atlas_connection_select_cluster.png + :alt: The connect button in the clusters section of the Atlas UI + + Proceed to the :guilabel:`Connect your application` section and select + "C++" from the :guilabel:`Driver` selection menu and the version + that best matches the version you installed from the :guilabel:`Version` + selection menu. + + Select the :guilabel:`Password (SCRAM)` authentication mechanism. + + Deselect the :guilabel:`Include full driver code example` option to view + only the connection string. + + .. step:: Copy your Connection String + + Click the button on the right of the connection string to copy it + to your clipboard, as shown in the following screenshot: + + .. figure:: /includes/figures/atlas_connection_copy_string_cpp.png + :alt: The copy button next to the connection string in the Atlas UI + + .. step:: Update the Placeholders + + Paste this connection string into a file in your preferred text editor + and replace the ```` and ```` placeholders with + your database user's username and password. + + Save this file to a safe location for use in the next step. + +After completing these steps, you have a connection string that +corresponds to your Atlas cluster. + +.. include:: /includes/get-started/troubleshoot.rst + +.. button:: Next: Connect to MongoDB + :uri: /get-started/connect-to-mongodb/ \ No newline at end of file diff --git a/source/get-started/create-a-deployment.txt b/source/get-started/create-a-deployment.txt new file mode 100644 index 00000000..ab5d40d4 --- /dev/null +++ b/source/get-started/create-a-deployment.txt @@ -0,0 +1,32 @@ +.. _cpp-quick-start-create-deployment: + +=========================== +Create a MongoDB Deployment +=========================== + +You can create a free tier MongoDB deployment on MongoDB Atlas +to store and manage your data. MongoDB Atlas hosts and manages +your MongoDB database in the cloud. + +.. procedure:: + :style: connected + + .. step:: Create a Free MongoDB deployment on Atlas + + Complete the :atlas:`Get Started with Atlas ` + guide to set up a new Atlas account and load sample data into a new free + tier MongoDB deployment. + + .. step:: Save your Credentials + + After you create your database user, save that user's + username and password to a safe location for use in an upcoming step. + +After you complete these steps, you have a new free tier MongoDB +deployment on Atlas, database user credentials, and sample data loaded +into your database. + +.. include:: /includes/get-started/troubleshoot.rst + +.. button:: Next: Create a Connection String + :uri: /get-started/create-a-connection-string/ \ No newline at end of file diff --git a/source/get-started/download-and-install.txt b/source/get-started/download-and-install.txt new file mode 100644 index 00000000..c3ff5914 --- /dev/null +++ b/source/get-started/download-and-install.txt @@ -0,0 +1,102 @@ +.. _cpp-quick-start-download-and-install: + +==================== +Download and Install +==================== + +.. facet:: + :name: genre + :values: tutorial + +.. meta:: + :keywords: cmake, code example + +.. procedure:: + :style: connected + + .. step:: Install dependencies + + Before you being developing, ensure you have the following dependencies + installed in your development environment: + + - Compiler that supports C++17, such as `GCC `__, `Clang `__, + or `Visual Studio `__ + - `CMake `__ v3.15 or later + - `pkg-config `__ + + .. step:: Download the {+driver-short+} + + To download the latest version of the {+driver-short+} from the ``mongo-cxx-driver`` Github + repository, run the following commands in your shell from your root directory: + + .. code-block:: bash + + curl -OL https://github.com/mongodb/mongo-cxx-driver/releases/download/r{+full-version+}/mongo-cxx-driver-r{+full-version+}.tar.gz + tar -xzf mongo-cxx-driver-r{+full-version+}.tar.gz + cd mongo-cxx-driver-r{+full-version+}/build + + .. step:: Configure the driver for installation + + Select the tab corresponding to your operating system and run following command from your + ``mongo-cxx-driver-r{+full-version+}/build`` directory: + + .. tabs:: + + .. tab:: macOS / Linux + :tabid: configure-mac-linux + + .. code-block:: bash + + cmake .. \ + -DCMAKE_BUILD_TYPE=Release \ + -DMONGOCXX_OVERRIDE_DEFAULT_INSTALL_PREFIX=OFF + + This command instructs CMake to install ``mongocxx`` into the ``/usr/local`` directory. + + .. tab:: Windows + :tabid: configure-windows + + .. code-block:: bash + + 'C:\\cmake.exe' .. \ + -G "Visual Studio " -A "x64" \ + -DCMAKE_CXX_STANDARD=17 \ + -DCMAKE_INSTALL_PREFIX=C:\mongo-cxx-driver \ + + This command instructs CMake to install ``mongocxx`` into the ``C:\mongo-cxx-driver`` + directory. Replace the following placeholder values: + + - ````: the path to your CMake executable + - ````: your Visual Studio version number + - ````: the year corresponding to your Visual Studio version + + .. step:: Build and install the driver + + Select the tab corresponding to your operating system and run following commands to install + the driver: + + .. tabs:: + + .. tab:: macOS / Linux + :tabid: configure-mac-linux + + .. code-block:: bash + + cmake --build . + sudo cmake --build . --target install + + .. tab:: Windows + :tabid: configure-windows + + .. code-block:: bash + + cmake --build . --config RelWithDebInfo + cmake --build . --target install --config RelWithDebInfo + +After you complete these steps, you have the {+driver-short+} installed +on your machine. + +.. include:: /includes/get-started/troubleshoot.rst + +.. button:: Next: Create a MongoDB Deployment + :uri: /get-started/create-a-deployment/ diff --git a/source/get-started/next-steps.txt b/source/get-started/next-steps.txt new file mode 100644 index 00000000..f0bb041d --- /dev/null +++ b/source/get-started/next-steps.txt @@ -0,0 +1,23 @@ +.. _cpp-quick-start-next-steps: + +========== +Next Steps +========== + +.. facet:: + :name: genre + :values: reference + +.. meta:: + :keywords: learn more + +Congratulations on completing the quick start tutorial! + +In this tutorial, you created a C++ application that +connects to a MongoDB deployment hosted on MongoDB Atlas +and retrieves a document that matches a query. + +.. TODO: add links once these pages exist + Learn more about {+driver-short+} from the following resources: + - Learn how to perform read operations in the :ref:`` section. + - Learn how to perform write operations in the :ref:`` section. \ No newline at end of file diff --git a/source/getting-help.txt b/source/getting-help.txt deleted file mode 100644 index 7593d790..00000000 --- a/source/getting-help.txt +++ /dev/null @@ -1,27 +0,0 @@ -.. _cpp-getting-help: - -============ -Getting Help -============ - -.. contents:: On this page - :local: - :backlinks: none - :depth: 1 - :class: singlecol - -.. facet:: - :name: genre - :values: reference - -.. meta:: - :keywords: community, forum, support - -Often, the quickest way to get support for general questions is through the -:community-forum:`MongoDB Community Forums ` -or through -`Stack Overflow `__. - -Please also refer to MongoDB's -`support channels `__ documentation. - diff --git a/source/includes/aggregation.cpp b/source/includes/aggregation.cpp new file mode 100644 index 00000000..b0618c6a --- /dev/null +++ b/source/includes/aggregation.cpp @@ -0,0 +1,57 @@ +#include + +#include +#include +#include +#include +#include +#include +#include + +using bsoncxx::builder::basic::kvp; +using bsoncxx::builder::basic::make_document; + +int main() { + mongocxx::instance instance; + mongocxx::uri uri(""); + mongocxx::client client(uri); + + auto db = client["sample_restaurants"]; + auto collection = db["restaurants"]; + + { + // Retrieves documents with a cuisine value of "Bakery", groups them by "borough", and + // counts each borough's matching documents + // start-match-group + mongocxx::pipeline stages; + + stages.match(make_document(kvp("cuisine", "Bakery"))) + .group(make_document(kvp("_id", "$borough"), kvp("count", make_document(kvp("$sum", 1))))); + + auto cursor = collection.aggregate(stages); + + for (auto&& doc : cursor) { + std::cout << bsoncxx::to_json(doc) << std::endl; + } + // end-match-group + } + + { + // Performs the same aggregation operation as above but asks MongoDB to explain it + // start-explain + mongocxx::pipeline stages; + + stages.match(make_document(kvp("cuisine", "Bakery"))) + .group(make_document(kvp("_id", "$borough"), kvp("count", make_document(kvp("$sum", 1))))); + + auto command = make_document( + kvp("explain", make_document( + kvp("aggregate", "restaurants"), + kvp("pipeline", stages.view_array()), + kvp("cursor", make_document())))); + + auto result = db.run_command(command.view()); + std::cout << bsoncxx::to_json(result) << std::endl; + // end-explain + } +} \ No newline at end of file diff --git a/source/includes/assumes-instance.rst b/source/includes/assumes-instance.rst new file mode 100644 index 00000000..030332eb --- /dev/null +++ b/source/includes/assumes-instance.rst @@ -0,0 +1,6 @@ +.. note:: mongocxx::instance + + The code examples on this page assume that you've already created a ``mongocxx::instance`` + object elsewhere in your application. + + To learn more about creating an instance, see :ref:`cpp-instance`. \ No newline at end of file diff --git a/source/includes/authentication.cpp b/source/includes/authentication.cpp new file mode 100644 index 00000000..3e072ce9 --- /dev/null +++ b/source/includes/authentication.cpp @@ -0,0 +1,48 @@ +// start-scram-sha-256 +auto uri = mongocxx::uri("mongodb://:@:/?" + "authSource=admin&authMechanism=SCRAM-SHA-256"); +auto client = mongocxx::client(uri); +// end-scram-sha-256 + +// start-scram-sha-1 +auto uri = mongocxx::uri("mongodb://:@:/?" + "authSource=admin&authMechanism=SCRAM-SHA-1"); +auto client = mongocxx::client(uri); +// end-scram-sha-1 + +// start-x509 +auto uri = mongocxx::uri("mongodb://:/?" + "tls=true&tlsCertificateKeyFile=path/to/client.pem&authMechanism=MONGODB-X509"); +auto client = mongocxx::client(uri); +// end-x509 + +// start-aws-connection-uri +auto uri = mongocxx::uri("mongodb://:@:/?" + "authMechanism=MONGODB-AWS"); +auto client = mongocxx::client(uri); +// end-aws-connection-uri + +// start-aws-connection-uri-session +auto uri = mongocxx::uri("mongodb://:@:/?" + "authMechanism=MONGODB-AWSS&authMechanismProperties=AWS_SESSION_TOKEN:"); +auto client = mongocxx::client(uri); +// end-aws-connection-uri-session + +// start-aws-environment +auto uri = mongocxx::uri("mongodb://:/?" + "authMechanism=MONGODB-AWS"); +auto client = mongocxx::client(uri); +// end-aws-environment + +// start-kerberos +auto uri = mongocxx::uri("mongodb://mongodbuser%40EXAMPLE.COM@:/?" + "authMechanism=GSSAPI" + "&authMechanismProperties=SERVICE_NAME:"); +auto client = mongocxx::client(uri); +// end-kerberos + +// start-plain +auto uri = mongocxx::uri("mongodb://:@:/?" + "authMechanism=PLAIN&tls=true"); +auto client = mongocxx::client(uri); +// end-plain \ No newline at end of file diff --git a/source/includes/connect/atlas.cpp b/source/includes/connect/atlas.cpp new file mode 100644 index 00000000..96bed636 --- /dev/null +++ b/source/includes/connect/atlas.cpp @@ -0,0 +1,37 @@ +#include +#include +#include +#include +#include + +using bsoncxx::builder::basic::kvp; +using bsoncxx::builder::basic::make_document; + +int main() +{ + mongocxx::instance instance; + + // Replace the placeholder with your Atlas connection string + mongocxx::uri uri(""); + + // Create a mongocxx::client with a mongocxx::options::client object to set the Stable API version + mongocxx::options::client client_options; + mongocxx::options::server_api server_api_options(mongocxx::options::server_api::version::k_version_1); + client_options.server_api_opts(server_api_options); + mongocxx::client client(uri, client_options); + + try + { + // Ping the server to verify that the connection works + auto admin = client["admin"]; + auto command = make_document(kvp("ping", 1)); + auto result = admin.run_command(command.view()); + std::cout << bsoncxx::to_json(result) << "\n"; + std::cout << "Pinged your deployment. You successfully connected to MongoDB!\n"; + } + catch (const mongocxx::exception &e) + { + std::cerr << "An exception occurred: " << e.what() << "\n"; + return EXIT_FAILURE; + } +} \ No newline at end of file diff --git a/source/includes/connect/ca-dir.cpp b/source/includes/connect/ca-dir.cpp new file mode 100644 index 00000000..1cc1fe95 --- /dev/null +++ b/source/includes/connect/ca-dir.cpp @@ -0,0 +1,8 @@ +mongocxx::options::client client_options; +mongocxx::options::tls tls_options; + +tls_options.ca_dir("/path/to/search/"); +client_options.tls_opts(tls_options); + +mongocxx::uri uri("mongodb://:/?tls=true"); +mongocxx::client client(uri, client_options); \ No newline at end of file diff --git a/source/includes/connect/ca-file-tabs.rst b/source/includes/connect/ca-file-tabs.rst new file mode 100644 index 00000000..e7675389 --- /dev/null +++ b/source/includes/connect/ca-file-tabs.rst @@ -0,0 +1,22 @@ +.. tabs:: + + .. tab:: mongocxx::options::tls + :tabid: tlsoptions + + .. code-block:: cpp + + mongocxx::options::client client_options; + mongocxx::options::tls tls_options; + + tls_options.pem_file("/path/to/file.pem"); + client_options.tls_opts(tls_options); + + mongocxx::uri uri("mongodb://:/?tls=true"); + mongocxx::client client(uri, client_options); + + .. tab:: Connection String + :tabid: connectionstring + + .. code-block:: cpp + + mongocxx::uri uri("mongodb://:/?tls=true&tlsCAFile=/path/to/file.pem"); diff --git a/source/includes/connect/client-cert-tabs.rst b/source/includes/connect/client-cert-tabs.rst new file mode 100644 index 00000000..6a47e950 --- /dev/null +++ b/source/includes/connect/client-cert-tabs.rst @@ -0,0 +1,22 @@ +.. tabs:: + + .. tab:: mongocxx::options::tls + :tabid: tlsoptions + + .. code-block:: cpp + + mongocxx::options::client client_options; + mongocxx::options::tls tls_options; + + tls_options.pem_file("/path/to/file.pem"); + client_options.tls_opts(tls_options); + + mongocxx::uri uri("mongodb://:/?tls=true"); + mongocxx::client client(uri, client_options); + + .. tab:: Connection String + :tabid: connectionstring + + .. code-block:: cpp + + mongocxx::uri uri("mongodb://:/?tls=true&tlsCertificateKeyFile=/path/to/file.pem"); \ No newline at end of file diff --git a/source/includes/connect/client.cpp b/source/includes/connect/client.cpp new file mode 100644 index 00000000..b612c9e0 --- /dev/null +++ b/source/includes/connect/client.cpp @@ -0,0 +1,10 @@ +#include +#include +#include + +int main() +{ + mongocxx::instance instance; + mongocxx::uri uri("mongodb://localhost:27017"); + mongocxx::client client(uri); +} \ No newline at end of file diff --git a/source/includes/connect/connection-options.cpp b/source/includes/connect/connection-options.cpp new file mode 100644 index 00000000..75df8d62 --- /dev/null +++ b/source/includes/connect/connection-options.cpp @@ -0,0 +1,45 @@ +// start-connection-uri +#include +#include +#include + +int main() +{ + mongocxx::instance instance; + mongocxx::uri uri("mongodb://:/?tls=true&tlsCertificateKeyFile=path/to/file.pem"); + mongocxx::client client(uri); +} +// end-connection-uri + +// start-client-options +#include +#include +#include + +int main() +{ + mongocxx::instance instance; + mongocxx::options::client client_options; + mongocxx::options::tls tls_options; + + tls_options.pem_file("/path/to/file.pem"); + client_options.tls_opts(tls_options); + + mongocxx::uri uri("mongodb://:/?tls=true"); + mongocxx::client client(uri, client_options); +} +// end-client-options + +// start-uri-object +#include +#include +#include + +int main() +{ + mongocxx::instance instance; + mongocxx::uri uri("mongodb://:/?tls=true"); + mongocxx::client client(uri); + auto is_tls_enabled = uri.tls(); +} +// end-uri-object \ No newline at end of file diff --git a/source/includes/connect/crl-file.cpp b/source/includes/connect/crl-file.cpp new file mode 100644 index 00000000..1fe0aa9a --- /dev/null +++ b/source/includes/connect/crl-file.cpp @@ -0,0 +1,8 @@ +mongocxx::options::client client_options; +mongocxx::options::tls tls_options; + +tls_options.crl_file("/path/to/file.pem"); +client_options.tls_opts(tls_options); + +mongocxx::uri uri("mongodb://:/?tls=true"); +mongocxx::client client(uri, client_options); \ No newline at end of file diff --git a/source/includes/connect/direct-connection.cpp b/source/includes/connect/direct-connection.cpp new file mode 100644 index 00000000..6af24bda --- /dev/null +++ b/source/includes/connect/direct-connection.cpp @@ -0,0 +1,10 @@ +#include +#include +#include + +int main() +{ + mongocxx::instance instance; + mongocxx::uri uri("mongodb://:/?directConnection=true"); + mongocxx::client client(uri); +} \ No newline at end of file diff --git a/source/includes/connect/disable-cert-validation-tabs.rst b/source/includes/connect/disable-cert-validation-tabs.rst new file mode 100644 index 00000000..afa85c70 --- /dev/null +++ b/source/includes/connect/disable-cert-validation-tabs.rst @@ -0,0 +1,22 @@ +.. tabs:: + + .. tab:: mongocxx::options::tls + :tabid: tlsoptions + + .. code-block:: cpp + + mongocxx::options::client client_options; + mongocxx::options::tls tls_options; + + tls_options.allow_invalid_certificates(true); + client_options.tls_opts(tls_options); + + mongocxx::uri uri("mongodb://:/?tls=true"); + mongocxx::client client(uri, client_options); + + .. tab:: Connection String + :tabid: connectionstring + + .. code-block:: cpp + + mongocxx::uri uri("mongodb://:/?tls=true&tlsAllowInvalidCertificates=true"); \ No newline at end of file diff --git a/source/includes/connect/instance.cpp b/source/includes/connect/instance.cpp new file mode 100644 index 00000000..800e58d2 --- /dev/null +++ b/source/includes/connect/instance.cpp @@ -0,0 +1,6 @@ +#include + +int main() +{ + mongocxx::instance instance; +} \ No newline at end of file diff --git a/source/includes/connect/key-file-password.rst b/source/includes/connect/key-file-password.rst new file mode 100644 index 00000000..85952fbf --- /dev/null +++ b/source/includes/connect/key-file-password.rst @@ -0,0 +1,23 @@ +.. tabs:: + + .. tab:: mongocxx::options::tls + :tabid: tlsoptions + + .. code-block:: cpp + + mongocxx::options::client client_options; + mongocxx::options::tls tls_options; + + tls_options.pem_file("/path/to/file.pem"); + tls_options.pem_password(""); + client_options.tls_opts(tls_options); + + mongocxx::uri uri("mongodb://:/?tls=true"); + mongocxx::client client(uri, client_options); + + .. tab:: Connection String + :tabid: connectionstring + + .. code-block:: cpp + + mongocxx::uri uri("mongodb://:/?tls=true&tlsCertificateKeyFile=/path/to/file.pem&tlsCertificateKeyFilePassword="); \ No newline at end of file diff --git a/source/includes/connect/network-compression.cpp b/source/includes/connect/network-compression.cpp new file mode 100644 index 00000000..bdea2225 --- /dev/null +++ b/source/includes/connect/network-compression.cpp @@ -0,0 +1,25 @@ +// start-all-compression +#include +#include +#include + +int main() +{ + mongocxx::instance instance; + mongocxx::uri uri("mongodb://:/?compressors=snappy,zstd,zlib"); + mongocxx::client client(uri); +} +// end-all-compression + +// start-zlib-compression +#include +#include +#include + +int main() +{ + mongocxx::instance instance; + mongocxx::uri uri("mongodb://:/?compressors=zlib&zlibCompressionLevel=1"); + mongocxx::client client(uri); +} +// end-zlib-compression \ No newline at end of file diff --git a/source/includes/connect/replica-set.cpp b/source/includes/connect/replica-set.cpp new file mode 100644 index 00000000..48c7d7b1 --- /dev/null +++ b/source/includes/connect/replica-set.cpp @@ -0,0 +1,10 @@ +#include +#include +#include + +int main() +{ + mongocxx::instance instance; + mongocxx::uri uri("mongodb://host1:27017/?replicaSet=sampleRS"); + mongocxx::client client(uri); +} \ No newline at end of file diff --git a/source/includes/connect/stable-api.cpp b/source/includes/connect/stable-api.cpp new file mode 100644 index 00000000..b4c76ee7 --- /dev/null +++ b/source/includes/connect/stable-api.cpp @@ -0,0 +1,35 @@ +// start-specify-v1 +#include +#include +#include + +int main() +{ + mongocxx::instance instance; + mongocxx::uri uri("mongodb://:"); + + mongocxx::options::server_api server_api_options(mongocxx::options::server_api::version::k_version_1); + mongocxx::options::client client_options; + client_options.server_api_opts(server_api_options); + mongocxx::client client(uri, client_options); +} +// end-specify-v1 + +// start-stable-api-options +#include +#include +#include + +int main() +{ + mongocxx::instance instance; + mongocxx::uri uri("mongodb://:"); + + mongocxx::options::server_api server_api_options(mongocxx::options::server_api::version::k_version_1); + server_api_options.strict(true); + server_api_options.deprecation_errors(true); + mongocxx::options::client client_options; + client_options.server_api_opts(server_api_options); + mongocxx::client client(uri, client_options); +} +// end-stable-api-options \ No newline at end of file diff --git a/source/includes/data-formats/time-series.cpp b/source/includes/data-formats/time-series.cpp new file mode 100644 index 00000000..ad2e2e0f --- /dev/null +++ b/source/includes/data-formats/time-series.cpp @@ -0,0 +1,62 @@ +#include +#include + +#include +#include +#include +#include +#include + +using bsoncxx::builder::basic::kvp; +using bsoncxx::builder::basic::make_document; + +int main() { + mongocxx::instance instance; + mongocxx::uri uri(""); + mongocxx::client client(uri); + + { + // Creates a time series collection to store precipitation data + // start-create-ts + auto db = client["precipitation"]; + + auto ts_info = make_document( + kvp("timeseries", make_document( + kvp("timeField", "timestamp"), + kvp("metaField", "location"), + kvp("granularity", "minutes") + ))); + + auto collection = db.create_collection("sept2023", ts_info.view()); + // end-create-ts + } + + { + // Lists the collections in the "precipitation" database + auto db = client["precipitation"]; + // start-list-colls + auto cursor = db.list_collections(); + + for(auto&& doc : cursor) { + std::cout << bsoncxx::to_json(doc) << std::endl; + } + // end-list-colls + } + + { + // Inserts precipitation time series data about New York City into the collection + auto db = client["precipitation"]; + // start-insert-ts + auto collection = db["sept2023"]; + std::vector ts_data; + ts_data.push_back(make_document(kvp("precipitation_mm", 0.5), + kvp("location", "New York City"), + kvp("timestamp", bsoncxx::types::b_date{std::chrono::milliseconds{1694829060000}}))); + ts_data.push_back(make_document(kvp("precipitation_mm", 2.8), + kvp("location", "New York City"), + kvp("timestamp", bsoncxx::types::b_date{std::chrono::milliseconds{1695594780000}}))); + + auto result = collection.insert_many(ts_data); + // end-insert-ts + } +} \ No newline at end of file diff --git a/source/includes/figures/atlas_connection_copy_string_cpp.png b/source/includes/figures/atlas_connection_copy_string_cpp.png new file mode 100644 index 00000000..a9845722 Binary files /dev/null and b/source/includes/figures/atlas_connection_copy_string_cpp.png differ diff --git a/source/includes/figures/atlas_connection_select_cluster.png b/source/includes/figures/atlas_connection_select_cluster.png new file mode 100644 index 00000000..52d827d6 Binary files /dev/null and b/source/includes/figures/atlas_connection_select_cluster.png differ diff --git a/source/includes/get-started/quickstart.cpp b/source/includes/get-started/quickstart.cpp new file mode 100644 index 00000000..ef4c0274 --- /dev/null +++ b/source/includes/get-started/quickstart.cpp @@ -0,0 +1,24 @@ +#include +#include +#include + +#include +#include +#include +#include +#include + +using bsoncxx::builder::basic::kvp; +using bsoncxx::builder::basic::make_document; + +int main() { + mongocxx::instance instance; + mongocxx::uri uri(""); + mongocxx::client client(uri); + auto db = client["sample_mflix"]; + auto collection = db["movies"]; + + auto result = collection.find_one(make_document(kvp("title", "The Shawshank Redemption"))); + std::cout << bsoncxx::to_json(*result) << std::endl; + +} \ No newline at end of file diff --git a/source/includes/get-started/troubleshoot.rst b/source/includes/get-started/troubleshoot.rst new file mode 100644 index 00000000..343871fc --- /dev/null +++ b/source/includes/get-started/troubleshoot.rst @@ -0,0 +1,6 @@ +.. note:: + + If you run into issues on this step, ask for help in the + :community-forum:`MongoDB Community Forums ` + or submit feedback by using the :guilabel:`Rate this page` + tab on the right or bottom right side of this page. \ No newline at end of file diff --git a/source/includes/indexes/indexes.cpp b/source/includes/indexes/indexes.cpp new file mode 100644 index 00000000..54ff574b --- /dev/null +++ b/source/includes/indexes/indexes.cpp @@ -0,0 +1,16 @@ +// start-index-single +auto index_specification = make_document(kvp("title", 1)); +collection.create_index(index_specification.view()); +// end-index-single + +// start-remove-index +collection.indexes().drop_one("title_1"); +// end-remove-index + +// start-remove-all-indexes +collection.indexes().drop_all(); +// end-remove-all-indexes + +// start-remove-all-wildcard +collection.indexes().drop_one("*"); +// end-remove-all-wildcard \ No newline at end of file diff --git a/source/includes/language-compatibility-table-cxx.rst b/source/includes/language-compatibility-table-cxx.rst index f39b9ec9..e9ee8f28 100644 --- a/source/includes/language-compatibility-table-cxx.rst +++ b/source/includes/language-compatibility-table-cxx.rst @@ -8,24 +8,14 @@ - C++17 - C++14 - C++11 - - C++03 - * - 3.8+ + * - 3.8 to 3.10 - ✓ - ✓ - ✓ - ✓ - - - - * - <= 3.7 - - - - ✓ - - ✓ - - ✓ - - - * - 1.x - - + * - 3.0 to 3.7 - - ✓ - ✓ diff --git a/source/includes/mongodb-compatibility-table-cxx.rst b/source/includes/mongodb-compatibility-table-cxx.rst index 9f47cffa..db8fd1b5 100644 --- a/source/includes/mongodb-compatibility-table-cxx.rst +++ b/source/includes/mongodb-compatibility-table-cxx.rst @@ -1,5 +1,3 @@ -.. sharedinclude:: dbx/compatibility-table-legend.rst - .. list-table:: :header-rows: 1 :stub-columns: 1 @@ -19,7 +17,7 @@ - MongoDB 2.6 - MongoDB 2.4 - * - 3.8+ + * - 3.8 to 3.10 - ✓ - ✓ - ✓ @@ -61,21 +59,7 @@ - - - * - 3.5 - - ⊛ - - ⊛ - - ⊛ - - ⊛ - - ⊛ - - ✓ - - ✓ - - ✓ - - ✓ - - ✓ - - - - - - * - 3.4 + * - 3.4 to 3.5 - ⊛ - ⊛ - ⊛ @@ -103,21 +87,7 @@ - - - * - 3.2 - - - - - - - - - - - - - - - - ✓ - - ✓ - - ✓ - - ✓ - - ✓ - - * - 3.1 + * - 3.1 to 3.2 - - - diff --git a/source/includes/read/change-streams.cpp b/source/includes/read/change-streams.cpp new file mode 100644 index 00000000..d46ebf61 --- /dev/null +++ b/source/includes/read/change-streams.cpp @@ -0,0 +1,73 @@ +#include + +#include +#include +#include +#include +#include + +using bsoncxx::builder::basic::kvp; +using bsoncxx::builder::basic::make_document; + +int main() { + mongocxx::instance instance; + mongocxx::uri uri(""); + mongocxx::client client(uri); + + // start-db-coll + auto db = client["sample_restaurants"]; + auto collection = db["restaurants"]; + // end-db-coll + + { + // Monitors and prints changes to the "restaurants" collection + // start-open-change-stream + auto stream = collection.watch(); + while (true) { + for (const auto& event : stream) { + std::cout << bsoncxx::to_json(event) << std::endl; + } + } + // end-open-change-stream + } + + { + // Updates a document that has a "name" value of "Blarney Castle" + // start-update-for-change-stream + auto result = collection.update_one(make_document(kvp("name", "Blarney Castle")), + make_document(kvp("$set", + make_document(kvp("cuisine", "Irish"))))); + // end-update-for-change-stream + } + + { + // Passes a pipeline argument to watch() to monitor only update operations + // start-change-stream-pipeline + mongocxx::pipeline pipeline; + pipeline.match(make_document(kvp("operationType", "update"))); + auto stream = collection.watch(pipeline); + + while (true) { + for (const auto& event : stream) { + std::cout << bsoncxx::to_json(event) << std::endl; + } + } + // end-change-stream-pipeline + } + + { + // Passes an options argument to watch() to include the post-image of updated documents + // start-change-stream-post-image + mongocxx::options::change_stream opts; + opts.full_document("updateLookup"); + auto stream = collection.watch(opts); + + while (true) { + for (const auto& event : stream) { + std::cout << bsoncxx::to_json(event) << std::endl; + } + } + // end-change-stream-post-image + } + +} \ No newline at end of file diff --git a/source/includes/read/count.cpp b/source/includes/read/count.cpp new file mode 100644 index 00000000..d699c9f9 --- /dev/null +++ b/source/includes/read/count.cpp @@ -0,0 +1,64 @@ +#include + +#include +#include +#include +#include + +using bsoncxx::builder::basic::kvp; +using bsoncxx::builder::basic::make_document; + +int main() { + mongocxx::instance instance; + mongocxx::uri uri(""); + mongocxx::client client(uri); + + // start-db-coll + auto db = client["sample_training"]; + auto collection = db["companies"]; + // end-db-coll + + { + // Counts all documents in the collection + // start-count-all + auto result = collection.count_documents({}); + std::cout << "Number of documents: " << result << std::endl; + // end-count-all + } + + { + // Counts documents that have a "founded_year" value of 2010 + // start-count-accurate + auto result = collection.count_documents(make_document(kvp("founded_year", 2010))); + std::cout << "Number of companies founded in 2010: " << result << std::endl; + // end-count-accurate + } + + { + // Counts a maximum of 100 documents that have a "number_of_employees" value of 50 + // start-modify-accurate + mongocxx::options::count opts; + opts.limit(100); + auto result = collection.count_documents(make_document(kvp("number_of_employees", 50)), opts); + std::cout << "Number of companies with 50 employees: " << result << std::endl; + // end-modify-accurate + } + + { + // Estimates the number of documents in the collection + // start-count-estimate + auto result = collection.estimated_document_count(); + std::cout << "Estimated number of documents: " << result << std::endl; + // end-count-estimate + } + + { + // Estimates the number of documents in the collection and sets a time limit on the operation + // start-modify-estimate + mongocxx::options::estimated_document_count opts; + opts.max_time(std::chrono::milliseconds{1000}); + auto result = collection.estimated_document_count(opts); + std::cout << "Estimated number of documents: " << result << std::endl; + // end-modify-estimate + } +} \ No newline at end of file diff --git a/source/includes/read/cursor.cpp b/source/includes/read/cursor.cpp new file mode 100644 index 00000000..0ecf910c --- /dev/null +++ b/source/includes/read/cursor.cpp @@ -0,0 +1,80 @@ +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +using bsoncxx::builder::basic::document; +using bsoncxx::builder::basic::kvp; +using bsoncxx::builder::basic::make_document; + +int main() { + mongocxx::instance instance; + mongocxx::uri uri(""); + mongocxx::client client(uri); + + // start-db-coll + auto db = client["sample_restaurants"]; + auto collection = db["restaurants"]; + // end-db-coll + + { + // Iterates over and prints all documents that have a "name" value of "Dunkin' Donuts" + // start-cursor-all + auto cursor = collection.find(make_document(kvp("name", "Dunkin' Donuts"))); + for(auto&& doc : cursor) { + std::cout << bsoncxx::to_json(doc) << std::endl; + } + // end-cursor-all + } + + { + // Retrieves and prints the first document stored in the cursor + // start-cursor-first + auto cursor = collection.find(make_document(kvp("name", "Dunkin' Donuts"))); + auto doc = cursor.begin(); + std::cout << bsoncxx::to_json(*doc) << std::endl; + // end-cursor-first + } + + { + // Creates a collection with a maximum size and inserts documents representing vegetables + // start-capped-coll + auto db = client["db"]; + auto collection = db.create_collection("vegetables", make_document(kvp("capped", true), kvp("size", 1024 * 1024))); + + std::vector vegetables; + vegetables.push_back(make_document(kvp("name", "cauliflower"))); + vegetables.push_back(make_document(kvp("name", "zucchini"))); + + auto result = collection.insert_many(vegetables); + // end-capped-coll + + // Iterates over the initial query results and continues iterating until three documents are stored in the cursor + // by using a tailable cursor + // start-tailable + mongocxx::options::find opts{}; + opts.cursor_type(mongocxx::cursor::type::k_tailable); + auto cursor = collection.find({}, opts); + + int docs_found = 0; + while (docs_found < 3) { + for (auto&& doc : cursor) { + std::cout << bsoncxx::to_json(doc) << std::endl; + docs_found++; + } + + // Sleeps for 100 milliseconds before trying to access more documents + std::this_thread::sleep_for(std::chrono::milliseconds(100)); + } + // end-tailable + } + +} \ No newline at end of file diff --git a/source/includes/read/distinct.cpp b/source/includes/read/distinct.cpp new file mode 100644 index 00000000..ee6edb17 --- /dev/null +++ b/source/includes/read/distinct.cpp @@ -0,0 +1,61 @@ +#include + +#include +#include +#include +#include +#include + +using bsoncxx::builder::basic::kvp; +using bsoncxx::builder::basic::make_document; +using bsoncxx::builder::basic::make_array; + +int main() { + mongocxx::instance instance; + mongocxx::uri uri(""); + mongocxx::client client(uri); + + // start-db-coll + auto db = client["sample_restaurants"]; + auto collection = db["restaurants"]; + // end-db-coll + + { + // Retrieves distinct values of the "borough" field + // start-distinct + auto cursor = collection.distinct("borough", {}); + for(auto&& doc : cursor) { + std::cout << bsoncxx::to_json(doc) << std::endl; + } + // end-distinct + } + + { + // Retrieves distinct "borough" field values for documents with a "cuisine" value of "Italian" + // start-distinct-with-query + auto cursor = collection.distinct("borough", make_document(kvp("cuisine", "Italian"))); + for(auto&& doc : cursor) { + std::cout << bsoncxx::to_json(doc) << std::endl; + } + // end-distinct-with-query + } + + { + // Retrieves distinct "name" field values for documents matching the "borough" and "cuisine" fields query + // and attaches a comment to the operation + // start-distinct-with-comment + mongocxx::options::distinct opts{}; + opts.comment(bsoncxx::types::bson_value::view_or_value{"Bronx pizza restaurants"}); + + auto cursor = collection.distinct("name", + make_document(kvp("$and", + make_array(make_document(kvp("borough", "Bronx")), + make_document(kvp("cuisine", "Pizza"))))), + opts + ); + for (auto&& doc : cursor) { + std::cout << bsoncxx::to_json(doc) << std::endl; + } + // end-distinct-with-comment + } +} \ No newline at end of file diff --git a/source/includes/read/limit-skip-sort.cpp b/source/includes/read/limit-skip-sort.cpp new file mode 100644 index 00000000..a1b36871 --- /dev/null +++ b/source/includes/read/limit-skip-sort.cpp @@ -0,0 +1,74 @@ +#include + +#include +#include +#include +#include +#include + +using bsoncxx::builder::basic::kvp; +using bsoncxx::builder::basic::make_document; + +int main() { + mongocxx::instance instance; + mongocxx::uri uri(""); + mongocxx::client client(uri); + + // start-db-coll + auto db = client["sample_restaurants"]; + auto collection = db["restaurants"]; + // end-db-coll + + { + // Retrieves 5 documents that have a "cuisine" value of "Italian" + // start-limit-method + mongocxx::options::find opts{}; + opts.limit(5); + + auto cursor = collection.find(make_document(kvp("cuisine", "Italian")), opts); + for(auto&& doc : cursor) { + std::cout << bsoncxx::to_json(doc) << std::endl; + } + // end-limit-method + } + + { + // Retrieves documents with a "cuisine" value of "Italian" and sorts in ascending "name" order + // start-sort-method + mongocxx::options::find opts{}; + opts.sort(make_document(kvp("name", 1))); + + auto cursor = collection.find(make_document(kvp("cuisine", "Italian")), opts); + for(auto&& doc : cursor) { + std::cout << bsoncxx::to_json(doc) << std::endl; + } + // end-sort-method + } + + { + // Retrieves documents with a "borough" value of "Manhattan" but skips the first 10 results + // start-skip-method + mongocxx::options::find opts{}; + opts.skip(10); + + auto cursor = collection.find(make_document(kvp("borough", "Manhattan")), opts); + for(auto&& doc : cursor) { + std::cout << bsoncxx::to_json(doc) << std::endl; + } + // end-skip-method + } + + { + // Retrieves 5 documents with a "cuisine" value of "Italian", skips the first 10 results, + // and sorts by ascending "name" order + // start-limit-sort-skip + mongocxx::options::find opts{}; + opts.sort(make_document(kvp("name", 1))).limit(5).skip(10); + + auto cursor = collection.find(make_document(kvp("cuisine", "Italian")), opts); + for(auto&& doc : cursor) { + std::cout << bsoncxx::to_json(doc) << std::endl; + } + // end-limit-sort-skip + } +} diff --git a/source/includes/read/project.cpp b/source/includes/read/project.cpp new file mode 100644 index 00000000..43000d11 --- /dev/null +++ b/source/includes/read/project.cpp @@ -0,0 +1,56 @@ +#include + +#include +#include +#include +#include +#include + +using bsoncxx::builder::basic::kvp; +using bsoncxx::builder::basic::make_document; + +int main() { + mongocxx::instance instance; + mongocxx::uri uri(""); + mongocxx::client client(uri); + + // start-db-coll + auto db = client["sample_restaurants"]; + auto collection = db["restaurants"]; + // end-db-coll + + // Retrieves documents matching the "name" field query and projects their "name", "cuisine", and "borough" values + // start-project-include + mongocxx::options::find opts{}; + opts.projection(make_document(kvp("name", 1), kvp("cuisine", 1), kvp("borough", 1))); + + auto cursor = collection.find(make_document(kvp("name", "Emerald Pub")), opts); + for(auto&& doc : cursor) { + std::cout << bsoncxx::to_json(doc) << std::endl; + } + // end-project-include + + // Retrieves documents matching the "name" field query + // and projects their "name", "cuisine", and "borough" values while excluding the "_id" values + // start-project-include-without-id + mongocxx::options::find opts{}; + opts.projection(make_document(kvp("_id", 0), kvp("name", 1), kvp("cuisine", 1), kvp("borough", 1))); + + auto cursor = collection.find(make_document(kvp("name", "Emerald Pub")), opts); + for(auto&& doc : cursor) { + std::cout << bsoncxx::to_json(doc) << std::endl; + } + // end-project-include-without-id + + // Retrieves documents matching the "name" field query and excludes their "grades" and "address" values when printing + // start-project-exclude + mongocxx::options::find opts{}; + opts.projection(make_document(kvp("grades", 0), kvp("address", 0))); + + auto cursor = collection.find(make_document(kvp("name", "Emerald Pub")), opts); + for(auto&& doc : cursor) { + std::cout << bsoncxx::to_json(doc) << std::endl; + } + // end-project-exclude + +} diff --git a/source/includes/read/retrieve.cpp b/source/includes/read/retrieve.cpp new file mode 100644 index 00000000..45510e35 --- /dev/null +++ b/source/includes/read/retrieve.cpp @@ -0,0 +1,50 @@ +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +using bsoncxx::builder::basic::kvp; +using bsoncxx::builder::basic::make_document; + +int main() { + mongocxx::instance instance; + mongocxx::uri uri(""); + mongocxx::client client(uri); + + // start-db-coll + auto db = client["sample_training"]; + auto collection = db["companies"]; + // end-db-coll + + // Retrieves and prints one document that has a "name" value of "LinkedIn" + // start-find-one + auto result = collection.find_one(make_document(kvp("name", "LinkedIn"))); + std::cout << bsoncxx::to_json(*result) << std::endl; + // end-find-one + + // Retrieves documents that have a "founded_year" value of 1970 + // start-find-many + auto cursor = collection.find(make_document(kvp("founded_year", 1970))); + // end-find-many + + // Retrieves and prints documents that have a "founded_year" value of 1970 + // start-cursor + auto cursor = collection.find(make_document(kvp("founded_year", 1970))); + for(auto&& doc : cursor) { + std::cout << bsoncxx::to_json(doc) << std::endl; + } + // end-cursor + + // Retrieves and prints 5 documents that have a "number_of_employees" value of 1000 + // start-modify + mongocxx::options::find opts; + opts.limit(5); + auto cursor = collection.find(make_document(kvp("number_of_employees", 1000)), opts); + // end-modify +} diff --git a/source/includes/read/specify-queries.cpp b/source/includes/read/specify-queries.cpp new file mode 100644 index 00000000..af1fb825 --- /dev/null +++ b/source/includes/read/specify-queries.cpp @@ -0,0 +1,104 @@ +#include +#include +#include + +#include +#include +#include +#include +#include + +using bsoncxx::builder::basic::kvp; +using bsoncxx::builder::basic::make_document; +using bsoncxx::builder::basic::make_array; + +int main() { + mongocxx::instance instance; + // Accesses a collection and inserts documents representing fruits + // start-setup + mongocxx::uri uri(""); + mongocxx::client client(uri); + auto db = client["db"]; + auto collection = db["fruits"]; + + std::vector fruits; + fruits.push_back(make_document(kvp("_id", 1), kvp("name", "apples"), kvp("qty", 5), kvp("rating", 3), kvp("color", "red"), kvp("type", make_array("fuji", "honeycrisp")))); + fruits.push_back(make_document(kvp("_id", 2), kvp("name", "bananas"), kvp("qty", 7), kvp("rating", 4), kvp("color", "yellow"), kvp("type", make_array("cavendish")))); + fruits.push_back(make_document(kvp("_id", 3), kvp("name", "oranges"), kvp("qty", 6), kvp("rating", 2), kvp("type", make_array("naval", "mandarin")))); + fruits.push_back(make_document(kvp("_id", 4), kvp("name", "pineapples"), kvp("qty", 3), kvp("rating", 5), kvp("color", "yellow"))); + + auto result = collection.insert_many(fruits); + // end-setup + + { + // Retrieves documents in which the "color" value is "yellow" + // start-find-exact + auto cursor = collection.find(make_document(kvp("color", "yellow"))); + for (auto &&doc : cursor) + { + std::cout << bsoncxx::to_json(doc) << std::endl; + } + // end-find-exact + } + + { + // Retrieves all documents in the collection + // start-find-all + auto cursor = collection.find({}); + // end-find-all + } + + { + + // Retrieves and prints documents in which the "rating" value is greater than 2 + // start-find-comparison + auto cursor = collection.find(make_document(kvp("rating", make_document(kvp("$gt", 2))))); + for(auto&& doc : cursor) { + std::cout << bsoncxx::to_json(doc) << std::endl; + } + // end-find-comparison + } + + { + // Retrieves and prints documents that match one or both query filters + // start-find-logical + auto cursor = collection.find( + make_document(kvp("$or", + make_array(make_document(kvp("qty", make_document(kvp("$gt", 5)))), + make_document(kvp("color", "yellow")))))); + for (auto&& doc : cursor) { + std::cout << bsoncxx::to_json(doc) << std::endl; + } + // end-find-logical + } + + { + // Retrieves and prints documents in which the "type" array has 2 elements + // start-find-array + auto cursor = collection.find(make_document(kvp("type", make_document(kvp("$size", 2))))); + for(auto&& doc : cursor) { + std::cout << bsoncxx::to_json(doc) << std::endl; + } + // end-find-array + } + + { + // Retrieves and prints documents that have a "color" field + // start-find-element + auto cursor = collection.find(make_document(kvp("color", make_document(kvp("$exists", true))))); + for(auto&& doc : cursor) { + std::cout << bsoncxx::to_json(doc) << std::endl; + } + // end-find-element + } + + { + // Retrieves and prints documents in which the "name" value has at least two consecutive "p" characters + // start-find-evaluation + auto cursor = collection.find(make_document(kvp("name", make_document(kvp("$regex", "p{2,}"))))); + for(auto&& doc : cursor) { + std::cout << bsoncxx::to_json(doc) << std::endl; + } + // end-find-evaluation + } +} \ No newline at end of file diff --git a/source/includes/usage-examples/connect-code-examples.cpp b/source/includes/usage-examples/connect-code-examples.cpp new file mode 100644 index 00000000..79231db2 --- /dev/null +++ b/source/includes/usage-examples/connect-code-examples.cpp @@ -0,0 +1,107 @@ +#include +#include +#include + +int main() +{ + mongocxx::instance instance; + + { + // Connects to a local MongoDB deployment + // start-local + mongocxx::uri uri("mongodb://localhost:27017/"); + mongocxx::client client(uri); + // end-local + } + + { + // Connects to a MongoDB Atlas deployment + // start-atlas + mongocxx::uri uri(""); + mongocxx::client client(uri); + // end-atlas + } + + { + // Connects to a replica set + // start-replica-set + mongocxx::uri uri("mongodb://:/?replicaSet="); + mongocxx::client client(uri); + // end-replica-set + } + + { + // Connects to a MongoDB deployment and enables TLS + // start-enable-tls + mongocxx::uri uri("mongodb://:/?tls=true"); + mongocxx::client client(uri); + // end-enable-tls + } + + { + // Connects to a MongoDB deployment, enables TLS, and prevents OCSP endpoint checks + // start-disable-ocsp + mongocxx::uri uri("mongodb://:/?tls=true&tlsDisableOCSPEndpointCheck=true"); + mongocxx::client client(uri); + // end-disable-ocsp + } + + { + // Connects to a TLS-enabled deployment and instructs the driver to check the + // server certificate against a CRL + // start-crl + mongocxx::options::client client_options; + mongocxx::options::tls tls_options; + + tls_options.crl_file(""); + client_options.tls_opts(tls_options); + + mongocxx::uri uri("mongodb://:/?tls=true"); + mongocxx::client client(uri, client_options); + // end-crl + } + + { + // Connects to a TLS-enabled deployment and disables server certificate verification + // start-insecure-tls + mongocxx::uri uri("mongodb://:/?tls=true&tlsInsecure=true"); + mongocxx::client client(uri); + // end-insecure-tls + } + + { + // Connects to a TLS-enabled deployment and disables hostname verification + // start-disable-hostname + mongocxx::uri uri("mongodb://:/?tls=true&tlsAllowInvalidHostnames=true"); + mongocxx::client client(uri); + // end-disable-hostname + } + + { + // Enables compression for a MongoDB connection and specifies each compression algorithm + // start-compression-all + mongocxx::uri uri("mongodb://:/?compressors=snappy,zstd,zlib"); + mongocxx::client client(uri); + // end-compression-all + } + + { + // Enables zlib compression for a MongoDB connection + // start-compression-zlib + mongocxx::uri uri("mongodb://:/?compressors=zlib&zlibCompressionLevel=1"); + mongocxx::client client(uri); + // end-compression-zlib + } + + { + // Connects to a MongoDB deployment and enables the stable API + // start-stable-api + mongocxx::uri uri(""); + + mongocxx::options::client client_options; + mongocxx::options::server_api server_api_options(mongocxx::options::server_api::version::k_version_1); + client_options.server_api_opts(server_api_options); + mongocxx::client client(uri, client_options); + // end-stable-api + } +} \ No newline at end of file diff --git a/source/includes/usage-examples/connect-sample-app.cpp b/source/includes/usage-examples/connect-sample-app.cpp new file mode 100644 index 00000000..e7f8f3c4 --- /dev/null +++ b/source/includes/usage-examples/connect-sample-app.cpp @@ -0,0 +1,32 @@ +#include + +#include +#include +#include +#include + +#include + +int main() +{ + mongocxx::instance instance; + + try + { + // Start example code here + + // End example code here + + auto admin = client["admin"]; + admin.run_command(bsoncxx::from_json(R"({ "ping": 1 })")); + + std::cout << "Successfully pinged the MongoDB server." << std::endl; + } + catch (const mongocxx::exception &e) + { + std::cout << "An exception occurred: " << e.what() << std::endl; + return EXIT_FAILURE; + } + + return EXIT_SUCCESS; +} \ No newline at end of file diff --git a/source/includes/usage-examples/index-code-examples.cpp b/source/includes/usage-examples/index-code-examples.cpp new file mode 100644 index 00000000..85ea293b --- /dev/null +++ b/source/includes/usage-examples/index-code-examples.cpp @@ -0,0 +1,18 @@ +// start-single-field +auto index_specification = make_document(kvp("", 1)); +auto result = collection.create_index(index_specification.view()); + +std::cout << "Index created: " << bsoncxx::to_json(result) << std::endl; +// end-single-field + +// start-remove-index +collection.indexes().drop_one(""); + +std::cout << "Index dropped." << std::endl; +// end-remove-index + +// start-remove-all-indexes +collection.indexes().drop_all(); + +std::cout << "All indexes removed." << std::endl; +// end-remove-all-indexes \ No newline at end of file diff --git a/source/includes/usage-examples/read-code-examples.cpp b/source/includes/usage-examples/read-code-examples.cpp new file mode 100644 index 00000000..d9171f39 --- /dev/null +++ b/source/includes/usage-examples/read-code-examples.cpp @@ -0,0 +1,85 @@ +#include +#include +#include + +#include +#include +#include +#include +#include + +using bsoncxx::builder::basic::kvp; +using bsoncxx::builder::basic::make_document; +using bsoncxx::builder::basic::make_array; + +int main() { + mongocxx::instance instance; + mongocxx::uri uri(""); + mongocxx::client client(uri); + auto db = client["db"]; + auto collection = db["coll"]; + + { + // Retrieves one document that matches a query filter + // start-find-one + auto result = collection.find_one(make_document(kvp("", ""))); + std::cout << bsoncxx::to_json(*result) << std::endl; + // end-find-one + } + + { + // Retrieves all documents that match a query filter + // start-find-multiple + auto results = collection.find(make_document(kvp("", ""))); + for(auto&& doc : results) { + std::cout << bsoncxx::to_json(doc) << std::endl; + } + // end-find-multiple + } + + { + // Counts the number of documents in a collection + // start-count + auto result = collection.count_documents({}); + std::cout << result << std::endl; + // end-count + } + + { + // Counts the number of documents that match a query filter + // start-count-query + auto result = collection.count_documents(make_document(kvp("", ""))); + std::cout << result << std::endl; + // end-count-query + } + + { + // Estimates the number of documents in the collection + // start-count-estimate + auto result = collection.estimated_document_count(); + std::cout << result << std::endl; + // end-count-estimate + } + + { + // Retrieves distinct values of a specified field + // start-distinct + auto results = collection.distinct("", ""); + for(auto&& doc : results) { + std::cout << bsoncxx::to_json(doc) << std::endl; + } + // end-distinct + } + + { + // Monitors and prints data changes to the collection + // start-change-stream + auto stream = collection.watch(); + while (true) { + for (const auto& event : stream) { + std::cout << bsoncxx::to_json(event) << std::endl; + } + } + // end-change-stream + } +} \ No newline at end of file diff --git a/source/includes/usage-examples/sample-app-intro.rst b/source/includes/usage-examples/sample-app-intro.rst new file mode 100644 index 00000000..9a53d587 --- /dev/null +++ b/source/includes/usage-examples/sample-app-intro.rst @@ -0,0 +1,9 @@ +Sample Application +~~~~~~~~~~~~~~~~~~ + +You can use the following sample application to test the code examples on this +page. To use the sample application, perform the following steps: + +1. Ensure you have the {+driver-short+} installed in a location from which your project can import it. +#. Copy the following code and paste it into a new ``.cpp`` file within your project. +#. Copy a code example from this page and paste it within the highlighted section of the file. \ No newline at end of file diff --git a/source/includes/usage-examples/sample-app.cpp b/source/includes/usage-examples/sample-app.cpp new file mode 100644 index 00000000..3bc266bd --- /dev/null +++ b/source/includes/usage-examples/sample-app.cpp @@ -0,0 +1,33 @@ +#include + +#include +#include +#include +#include +#include +#include + +using bsoncxx::builder::basic::kvp; +using bsoncxx::builder::basic::make_document; + +int main() { + try { + mongocxx::instance instance; + + mongocxx::uri uri(""); + mongocxx::client client(uri); + + auto database = client[""]; + auto collection = database[""]; + + // Start example code here + + // End example code here + + } catch (const mongocxx::exception& e) { + std::cout << "An exception occurred: " << e.what() << "\n"; + return EXIT_FAILURE; + } + + return EXIT_SUCCESS; +} \ No newline at end of file diff --git a/source/includes/usage-examples/write-code-examples.cpp b/source/includes/usage-examples/write-code-examples.cpp new file mode 100644 index 00000000..d7c98d17 --- /dev/null +++ b/source/includes/usage-examples/write-code-examples.cpp @@ -0,0 +1,96 @@ +#include +#include +#include + +#include +#include +#include +#include +#include + +using bsoncxx::builder::basic::kvp; +using bsoncxx::builder::basic::make_document; +using bsoncxx::builder::basic::make_array; + +int main() { + mongocxx::instance instance; + mongocxx::uri uri(""); + mongocxx::client client(uri); + auto db = client["db"]; + auto collection = db["coll"]; + + { + // Inserts one document that stores the specified value + // start-insert-one + auto result = collection.insert_one(make_document(kvp("", ""))); + // end-insert-one + } + + { + // Inserts multiple documents that store the specified values + // start-insert-multiple + std::vector documents; + documents.push_back(make_document(kvp("", ""))); + documents.push_back(make_document(kvp("", ""))); + + auto result = collection.insert_many(documents); + // end-insert-multiple + } + + { + // Updates a document that matches the specified criteria + // start-update-one + auto query_filter = make_document(kvp("", "")); + auto update_doc = make_document(kvp("$set", make_document(kvp("", "")))); + + auto result = collection.update_one(query_filter.view(), update_doc.view()); + // end-update-one + } + + { + // Updates all documents that match the specified criteria + // start-update-multiple + auto query_filter = make_document(kvp("", "")); + auto update_doc = make_document(kvp("$set", make_document(kvp("", "")))); + + auto result = collection.update_many(query_filter.view(), update_doc.view()); + // end-update-multiple + } + + { + // Deletes a document that matches the specified criteria + // start-delete-one + auto result = collection.delete_one(make_document(kvp("", ""))); + // end-delete-one + } + + { + // Deletes all documents that match the specified criteria + // start-delete-multiple + auto result = collection.delete_many(make_document(kvp("", ""))); + // end-delete-multiple + } + + { + // Runs a bulk operation based on the instructions in each write model + // start-bulk-write + auto bulk = collection.create_bulk_write(); + + auto insert_doc = make_document(kvp("", "")); + auto update_filter = make_document(kvp("", "")); + auto update_doc = make_document(kvp("$set", make_document(kvp("", "")))); + auto delete_filter = make_document(kvp("", "")); + + mongocxx::model::insert_one insert_op{insert_doc.view()}; + mongocxx::model::update_many update_op{update_filter.view(), update_doc.view()}; + mongocxx::model::delete_one delete_op{delete_filter.view()}; + + bulk.append(insert_op); + bulk.append(update_op); + bulk.append(delete_op); + + auto result = bulk.execute(); + // end-bulk-write + } + +} \ No newline at end of file diff --git a/source/includes/write/bulk-write.cpp b/source/includes/write/bulk-write.cpp new file mode 100644 index 00000000..6b794199 --- /dev/null +++ b/source/includes/write/bulk-write.cpp @@ -0,0 +1,141 @@ +#include + +#include +#include +#include +#include +#include + +using bsoncxx::builder::basic::kvp; +using bsoncxx::builder::basic::make_document; + +int main() { + mongocxx::instance instance; + mongocxx::uri uri(""); + mongocxx::client client(uri); + + // start-db-coll + auto db = client["sample_restaurants"]; + auto collection = db["restaurants"]; + // end-db-coll + + // Creates a bulk_write instance to contain the write models + // start-create-bulk-write + auto bulk = collection.create_bulk_write(); + // end-create-bulk-write + + { + // Creates a write model to specify an insert operation and adds it to the bulk operation + // start-bulk-insert-one + auto insert_doc = make_document(kvp("name", "Mongo's Deli"), + kvp("cuisine", "Sandwiches"), + kvp("borough", "Manhattan"), + kvp("restaurant_id", "1234")); + + mongocxx::model::insert_one insert_op{insert_doc.view()}; + bulk.append(insert_op); + // end-bulk-insert-one + } + + { + // Creates a write model to specify an update one operation and adds it to the bulk operation + // start-bulk-update-one + auto filter_doc = make_document(kvp("name", "Mongo's Deli")); + auto update_doc = make_document(kvp("$set", make_document(kvp("cuisine", "Sandwiches and Salads")))); + + mongocxx::model::update_one update_op{filter_doc.view(), update_doc.view()}; + bulk.append(update_op); + // end-bulk-update-one + } + + { + // Creates a write model to specify an update many operation and adds it to the bulk operation + // start-bulk-update-many + auto filter_doc = make_document(kvp("name", "Mongo's Deli")); + auto update_doc = make_document(kvp("$set", make_document(kvp("cuisine", "Sandwiches and Salads")))); + + mongocxx::model::update_many update_op{filter_doc.view(), update_doc.view()}; + bulk.append(update_op); + // end-bulk-update-many + } + + { + // Creates a write model to specify a replace operation and adds it to the bulk operation + // start-bulk-replace-one + auto filter_doc = make_document(kvp("restaurant_id", "1234")); + auto replace_doc = make_document(kvp("name", "Mongo's Deli"), + kvp("cuisine", "Sandwiches and Salads"), + kvp("borough", "Brooklyn"), + kvp("restaurant_id", "5678")); + + mongocxx::model::replace_one replace_op{filter_doc.view(), replace_doc.view()}; + bulk.append(replace_op); + // end-bulk-replace-one + } + + { + // Creates a write model to specify a delete one operation and adds it to the bulk operation + // start-bulk-delete-one + auto filter_doc = make_document(kvp("restaurant_id", "5678")); + + mongocxx::model::delete_one delete_op{filter_doc.view()}; + bulk.append(delete_op); + // end-bulk-delete-one + } + + { + // Creates a write model to specify a delete many operation and adds it to the bulk operation + // start-bulk-delete-many + auto filter_doc = make_document(kvp("borough", "Manhattan")); + + mongocxx::model::delete_many delete_op{filter_doc.view()}; + bulk.append(delete_op); + // end-bulk-delete-many + } + + { + // Runs the bulk operation based on the instructions in each write model + // start-bulk-run + auto bulk = collection.create_bulk_write(); + + // Specifies documents to insert, update, replace, or delete + auto insert_doc = make_document(kvp("name", "Mongo's Deli"), + kvp("cuisine", "Sandwiches"), + kvp("borough", "Manhattan"), + kvp("restaurant_id", "1234")); + auto update_filter = make_document(kvp("name", "Mongo's Deli")); + auto update_doc = make_document(kvp("$set", make_document(kvp("cuisine", "Sandwiches and Salads")))); + auto replace_filter = make_document(kvp("restaurant_id", "1234")); + auto replace_doc = make_document(kvp("name", "Mongo's Deli"), + kvp("cuisine", "Sandwiches and Salads"), + kvp("borough", "Brooklyn"), + kvp("restaurant_id", "5678")); + auto delete_filter = make_document(kvp("borough", "Manhattan")); + + // Creates write models for each write operation using the preceding documents + mongocxx::model::insert_one insert_op{insert_doc.view()}; + mongocxx::model::update_many update_op{update_filter.view(), update_doc.view()}; + mongocxx::model::replace_one replace_op{replace_filter.view(), replace_doc.view()}; + mongocxx::model::delete_many delete_op{delete_filter.view()}; + + // Appends each write model to the bulk operation + bulk.append(insert_op); + bulk.append(update_op); + bulk.append(replace_op); + bulk.append(delete_op); + + // Runs the bulk operation + auto result = bulk.execute(); + std::cout << "Modified documents: " << result->modified_count() << std::endl; + // end-bulk-run + } + + { + // Creates a bulk_write instance and instructs the operation to not run in order + // start-bulk-write-unordered + mongocxx::options::bulk_write opts; + opts.ordered(false); + auto bulk = collection.create_bulk_write(opts); + // end-bulk-write-unordered + } +} \ No newline at end of file diff --git a/source/includes/write/delete.cpp b/source/includes/write/delete.cpp new file mode 100644 index 00000000..dafb1f3d --- /dev/null +++ b/source/includes/write/delete.cpp @@ -0,0 +1,56 @@ +#include + +#include +#include +#include +#include +#include + +using bsoncxx::builder::basic::kvp; +using bsoncxx::builder::basic::make_document; + +int main() { + mongocxx::instance instance; + mongocxx::uri uri(""); + mongocxx::client client(uri); + + // start-db-coll + auto db = client["sample_restaurants"]; + auto collection = db["restaurants"]; + // end-db-coll + + { + // Deletes a document that has a "name" value of "Ready Penny Inn" + // start-delete-one + auto result = collection.delete_one(make_document(kvp("name", "Ready Penny Inn"))); + // end-delete-one + } + + { + // Deletes documents that have a "borough" value of "Brooklyn" + // start-delete-many + auto result = collection.delete_many(make_document(kvp("borough", "Brooklyn"))); + // end-delete-many + } + + { + + // Deletes matching documents and attaches a comment to the operation + // start-delete-options + mongocxx::options::delete_options opts{}; + opts.comment(bsoncxx::types::bson_value::view_or_value{"Deleting Mongo restaurants"}); + + auto query_filter = make_document(kvp("name", make_document(kvp("$regex", "Mongo")))); + auto result = collection.delete_many(query_filter.view(), opts); + // end-delete-options + } + + { + // Deletes and prints the number of documents that have a "cuisine" value of "Greek" + // start-delete-count + auto result = collection.delete_many(make_document(kvp("cuisine", "Greek"))); + std::cout << result->deleted_count() << std::endl; + // end-delete-count + } + +} \ No newline at end of file diff --git a/source/includes/write/insert.cpp b/source/includes/write/insert.cpp new file mode 100644 index 00000000..083ce4f4 --- /dev/null +++ b/source/includes/write/insert.cpp @@ -0,0 +1,52 @@ +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +using bsoncxx::builder::basic::kvp; +using bsoncxx::builder::basic::make_document; + +int main() { + mongocxx::instance instance; + mongocxx::uri uri(""); + mongocxx::client client(uri); + + // start-db-coll + auto db = client["sample_restaurants"]; + auto collection = db["restaurants"]; + // end-db-coll + + // Inserts a document that stores a "name" value of "Mongo's Burgers" into the collection + // start-insert-one + auto result = collection.insert_one(make_document(kvp("name", "Mongo's Burgers"))); + // end-insert-one + + // Inserts documents representing restaurants into the collection + // start-insert-many + std::vector restaurants; + restaurants.push_back(make_document(kvp("name", "Mongo's Burgers"))); + restaurants.push_back(make_document(kvp("name", "Mongo's Pizza"))); + + auto result = collection.insert_many(restaurants); + // end-insert-many + + // Inserts multiple documents and instructs the insert operation to skip document-level validation + // start-modify + std::vector docs; + docs.push_back(make_document(kvp("name", "Mongo's Burgers"))); + docs.push_back(make_document(kvp("name", "Mongo's Pizza"))); + docs.push_back(make_document(kvp("name", "Mongo's Tacos"))); + + mongocxx::options::insert opts; + opts.bypass_document_validation(true); + + auto result = collection.insert_many(docs, opts); + // end-modify + +} \ No newline at end of file diff --git a/source/includes/write/update.cpp b/source/includes/write/update.cpp new file mode 100644 index 00000000..468a8864 --- /dev/null +++ b/source/includes/write/update.cpp @@ -0,0 +1,67 @@ +#include + +#include +#include +#include +#include +#include + +using bsoncxx::builder::basic::kvp; +using bsoncxx::builder::basic::make_document; + +int main() { + mongocxx::instance instance; + mongocxx::uri uri(""); + mongocxx::client client(uri); + + // start-db-coll + auto db = client["sample_restaurants"]; + auto collection = db["restaurants"]; + // end-db-coll + + { + // Updates the "name" value of a document from "Bagels N Buns" to "2 Bagels 2 Buns" + // start-update-one + auto query_filter = make_document(kvp("name", "Bagels N Buns")); + auto update_doc = make_document(kvp("$set", make_document(kvp("name", "2 Bagels 2 Buns")))); + + auto result = collection.update_one(query_filter.view(), update_doc.view()); + // end-update-one + } + + { + // Updates the "cuisine" value of documents from "Pizza" to "Pasta" + // start-update-many + auto query_filter = make_document(kvp("cuisine", "Pizza")); + auto update_doc = make_document(kvp("$set", make_document(kvp("cuisine", "Pasta")))); + + auto result = collection.update_many(query_filter.view(), update_doc.view()); + // end-update-many + } + + { + + // Updates the "borough" value of matching documents and inserts a document if none match + // start-update-options + mongocxx::options::update opts{}; + opts.upsert(true); + + auto query_filter = make_document(kvp("borough", "Manhattan")); + auto update_doc = make_document(kvp("$set", make_document(kvp("borough", "Manhattan (north)")))); + + auto result = collection.update_many(query_filter.view(), update_doc.view(), opts); + // end-update-options + } + + { + + // Updates the "name" value of matching documents and prints the number of updates + // start-update-result + auto query_filter = make_document(kvp("name", "Dunkin' Donuts")); + auto update_doc = make_document(kvp("$set", make_document(kvp("name", "Dunkin'")))); + + auto result = collection.update_many(query_filter.view(), update_doc.view()); + std::cout << "Modified documents: " << result->modified_count() << std::endl; + // end-update-result + } +} \ No newline at end of file diff --git a/source/index.txt b/source/index.txt index a6a5dbd9..112ec3e4 100644 --- a/source/index.txt +++ b/source/index.txt @@ -16,8 +16,16 @@ MongoDB C++ Driver :titlesonly: :maxdepth: 1 + Get Started + /connect /polyfill-selection /installation + /read + /write + /aggregation + /indexes + /security + /data-formats /configuration /client-side-encryption /tutorial @@ -25,11 +33,13 @@ MongoDB C++ Driver /connection-pools /working-with-bson /api-abi-versioning + /whats-new + /upgrade /reporting-bugs /testing - /contributing - /getting-help - API Documentation + /compatibility + /issues-and-help + API Documentation Driver Source Welcome to the MongoDB C++ driver. On this site, you'll find documentation diff --git a/source/indexes.txt b/source/indexes.txt new file mode 100644 index 00000000..15a1c315 --- /dev/null +++ b/source/indexes.txt @@ -0,0 +1,94 @@ +.. _cpp-indexes: + +============================= +Optimize Queries with Indexes +============================= + +.. contents:: On this page + :local: + :backlinks: none + :depth: 2 + :class: singlecol + +.. facet:: + :name: genre + :values: reference + +.. meta:: + :description: Learn how to use indexes with the {+driver-long+}. + :keywords: query, optimization, efficiency, usage example, code example + +.. toctree:: + :titlesonly: + :maxdepth: 1 + + /work-with-indexes + +Overview +-------- + +On this page, you can see copyable code examples that demonstrate how to use the +{+driver-short+} to work with common types of indexes. + +.. tip:: + + To learn more about working with indexes, see the :ref:`cpp-work-with-indexes` + guide. To learn more about any of the indexes shown on this page, see the link + provided in each section. + +To use an example from this page, copy the code example into the +:ref:`sample application ` or your own application. +Be sure to replace all placeholders in the code examples, such as ````, with +the relevant values for your MongoDB deployment. + +.. _cpp-index-sample: + +.. include:: /includes/usage-examples/sample-app-intro.rst + +.. literalinclude:: /includes/usage-examples/sample-app.cpp + :language: cpp + :copyable: + :linenos: + :emphasize-lines: 23-25 + +Single-Field Index +------------------ + +The following code shows how to create an ascending single-field index: + +.. literalinclude:: /includes/usage-examples/index-code-examples.cpp + :start-after: start-single-field + :end-before: end-single-field + :language: cpp + :copyable: + +To learn more about single-field indexes, see the +:ref:`cpp-single-field-index` section of the Work With Indexes guide. + +Remove an Index +--------------- + +The following code shows how to remove an index: + +.. literalinclude:: /includes/usage-examples/index-code-examples.cpp + :start-after: start-remove-index + :end-before: end-remove-index + :language: cpp + :copyable: + +To learn more about removing indexes, see the +:ref:`cpp-indexes-remove` section of the Work With Indexes guide. + +Remove All Indexes +------------------ + +The following code shows how to remove all indexes in a collection: + +.. literalinclude:: /includes/usage-examples/index-code-examples.cpp + :start-after: start-remove-all-indexes + :end-before: end-remove-all-indexes + :language: cpp + :copyable: + +To learn more about removing indexes, see the +:ref:`cpp-indexes-remove` section of the Work With Indexes guide. \ No newline at end of file diff --git a/source/issues-and-help.txt b/source/issues-and-help.txt new file mode 100644 index 00000000..84d0b5a3 --- /dev/null +++ b/source/issues-and-help.txt @@ -0,0 +1,53 @@ +.. _cpp-issues-help: + +============= +Issues & Help +============= + +.. contents:: On this page + :local: + :backlinks: none + :depth: 1 + :class: singlecol + +.. facet:: + :name: genre + :values: reference + +.. meta:: + :keywords: suggestion, github, style, contribute, PR + +We're glad to have such a vibrant community of {+driver-short+} +users. We recommend seeking support for general +questions through the :community-forum:`MongoDB Community Forums. ` + +You can also refer to +`Stack Overflow `__ +and MongoDB's +`support channels `__ documentation. + +Bugs / Feature Requests +----------------------- + +To report a bug or to request a new feature in the {+driver-short+}, +please open an issue in JIRA, our issue-management tool, using the +following steps: + +1. `Create a JIRA account `__. +#. Navigate to the `C++ Driver project `__. +#. Click :guilabel:`Create`. Please provide as much information as possible about the + issue and the steps to reproduce it. + +Bug reports in JIRA for the C++ Driver project can be viewed by everyone. + +If you identify a security vulnerability in the driver or in any other +MongoDB project, please report it according to the instructions found in +:manual:`Create a Vulnerability Report `. + +Pull Requests +------------- + +We are happy to accept contributions to help improve the driver. To +contribute to the official driver, follow the `contributing guidelines +`__. +We will guide user contributions to ensure they meet the standards of the codebase. \ No newline at end of file diff --git a/source/read.txt b/source/read.txt new file mode 100644 index 00000000..c8dddc44 --- /dev/null +++ b/source/read.txt @@ -0,0 +1,163 @@ +.. _cpp-read: + +====================== +Read Data from MongoDB +====================== + +.. contents:: On this page + :local: + :backlinks: none + :depth: 2 + :class: singlecol + +.. facet:: + :name: genre + :values: reference + +.. meta:: + :description: Learn how to use the C++ driver to read data from MongoDB. + :keywords: usage examples, query, find, code example + +.. toctree:: + :titlesonly: + :maxdepth: 1 + + /read/retrieve + /read/specify-a-query + /read/specify-documents-to-return + /read/project + /read/distinct + /read/count + /read/cursor + /read/change-streams + +Overview +-------- + +On this page, you can see copyable code examples that show common +{+driver-short+} methods for retrieving documents. + +.. tip:: + + To learn more about any of the methods shown on this page, see the link + provided in each section. + +To use an example from this page, copy the code example into the +:ref:`sample application ` or your own application. +Be sure to replace all placeholders, such as ````, with +the relevant values for your MongoDB deployment. + +.. _cpp-read-sample: + +.. include:: /includes/usage-examples/sample-app-intro.rst + +.. literalinclude:: /includes/usage-examples/sample-app.cpp + :language: cpp + :dedent: + :linenos: + :emphasize-lines: 23-25 + +Find One +-------- + +The following code shows how to retrieve a single document from a collection +that matches the specified criteria: + +.. literalinclude:: /includes/usage-examples/read-code-examples.cpp + :start-after: start-find-one + :end-before: end-find-one + :language: cpp + :dedent: + +To learn more about the ``find_one()`` method, see the :ref:`cpp-retrieve-find-one` +section in the Retrieve Data guide. + +Find Multiple +------------- + +The following code shows how to retrieve all documents from a collection +that match the specified criteria: + +.. literalinclude:: /includes/usage-examples/read-code-examples.cpp + :start-after: start-find-multiple + :end-before: end-find-multiple + :language: cpp + :dedent: + +To learn more about the ``find()`` method, see the :ref:`cpp-retrieve-find-multiple` +section in the Retrieve Data guide. + +Count Documents in a Collection +------------------------------- + +The following code shows how to count the number of documents in +a collection: + +.. literalinclude:: /includes/usage-examples/read-code-examples.cpp + :start-after: start-count + :end-before: end-count + :language: cpp + :dedent: + +To learn more about the ``count_documents()`` method, see the +:ref:`cpp-accurate-count` section in the Count Documents guide. + +Count Documents Returned from a Query +------------------------------------- + +The following code shows how to count documents in a collection +that match the specified criteria: + +.. literalinclude:: /includes/usage-examples/read-code-examples.cpp + :start-after: start-count-query + :end-before: end-count-query + :language: cpp + :dedent: + +To learn more about the ``count_documents()`` method, see the +:ref:`cpp-accurate-count` section in the Count Documents guide. + +Estimated Document Count +------------------------ + +The following code shows how to retrieve an estimated count of the +number of documents in a collection: + +.. literalinclude:: /includes/usage-examples/read-code-examples.cpp + :start-after: start-count-estimate + :end-before: end-count-estimate + :language: cpp + :dedent: + +To learn more about the ``estimated_document_count()`` method, see the +:ref:`cpp-estimated-count` section in the Count Documents guide. + +Retrieve Distinct Values +------------------------ + +The following code shows how to retrieve the unique values of a field +for documents that match the specified criteria: + +.. literalinclude:: /includes/usage-examples/read-code-examples.cpp + :start-after: start-distinct + :end-before: end-distinct + :language: cpp + :dedent: + +To learn more about the ``distinct()`` method, see the +:ref:`cpp-distinct` guide. + +Monitor Data Changes +-------------------- + +The following code shows how to monitor and print changes to a +collection: + +.. literalinclude:: /includes/usage-examples/read-code-examples.cpp + :start-after: start-change-stream + :end-before: end-change-stream + :language: cpp + :dedent: + +To learn more about the ``watch()`` method, see the +:ref:`cpp-change-streams` guide. diff --git a/source/read/change-streams.txt b/source/read/change-streams.txt new file mode 100644 index 00000000..30c49a3d --- /dev/null +++ b/source/read/change-streams.txt @@ -0,0 +1,271 @@ +.. _cpp-change-streams: + +==================== +Monitor Data Changes +==================== + +.. contents:: On this page + :local: + :backlinks: none + :depth: 2 + :class: singlecol + +.. facet:: + :name: genre + :values: reference + +.. meta:: + :keywords: watch, code example + +Overview +-------- + +In this guide, you can learn how to use a **change stream** to monitor real-time +changes to your database. A change stream is a {+mdb-server+} feature that +allows your application to subscribe to data changes on a collection, database, +or deployment. + +When using the {+driver-short+}, you can instantiate a ``mongocxx::change_stream`` to +monitor data changes. + +Sample Data +~~~~~~~~~~~ + +The examples in this guide use the ``restaurants`` collection in the ``sample_restaurants`` +database from the :atlas:`Atlas sample datasets `. To access this collection +from your C++ application, instantiate a ``mongocxx::client`` that connects to an Atlas cluster +and assign the following values to your ``db`` and ``collection`` variables: + +.. literalinclude:: /includes/read/change-streams.cpp + :language: cpp + :dedent: + :start-after: start-db-coll + :end-before: end-db-coll + +To learn how to create a free MongoDB Atlas cluster and load the sample datasets, see the +:atlas:`Get Started with Atlas ` guide. + +Open a Change Stream +-------------------- + +To open a change stream, call the ``watch()`` method. The instance on which you +call the ``watch()`` method on determines the scope of events that the change +stream listens for. You can call the ``watch()`` method on the following +classes: + +- ``mongocxx::client``: Monitor all changes in the MongoDB deployment +- ``mongocxx::database``: Monitor changes in all collections in the database +- ``mongocxx::collection``: Monitor changes in the collection + +The following example opens a change stream on the ``restaurants`` collection +and outputs changes as they occur: + +.. literalinclude:: /includes/read/change-streams.cpp + :start-after: start-open-change-stream + :end-before: end-open-change-stream + :language: cpp + :dedent: + +To begin watching for changes, run the preceding code. Then, in a separate +application or shell, modify the ``restaurants`` collection. The following +example updates a document that has a ``name`` field value of ``Blarney Castle``: + +.. _cpp-change-stream-update: + +.. literalinclude:: /includes/read/change-streams.cpp + :start-after: start-update-for-change-stream + :end-before: end-update-for-change-stream + :language: cpp + :dedent: + +When you update the collection, the change stream application prints the change +as it occurs. The printed change event resembles the following output: + +.. code-block:: bash + :copyable: false + + { "_id" : { "_data" : "..." }, "operationType" : "update", "clusterTime" : + { "$timestamp" : { ... }, "wallTime" : { "$date" : ... }, "ns" : + { "db" : "sample_restaurants", "coll" : "restaurants" }, "documentKey" : + { "_id" : { "$oid" : "..." } }, "updateDescription" : { "updatedFields" : + { "cuisine" : "Irish" }, "removedFields" : [ ], "truncatedArrays" : [ ] } } + +Modify the Change Stream Output +------------------------------- + +You can pass a ``mongocxx::pipeline`` instance as an argument to the ``watch()`` method +to modify the change stream output. The following list includes some of the ``mongocxx::pipeline`` +fields you can set by calling their corresponding setter methods: + +- ``add_fields``: Adds new fields to documents +- ``match``: Filters the documents +- ``project``: Projects a subset of the document fields +- ``redact``: Restricts the contents of the documents +- ``group``: Groups documents by a specified expression +- ``merge``: Outputs the results to a collection + +.. tip:: + + For a full list of ``mongocxx::pipeline`` fields, see the `mongocxx::pipeline + <{+api+}/classmongocxx_1_1v__noabi_1_1pipeline.html>`__ API documentation. + +The following example sets the ``match`` field of a ``mongocxx::pipeline`` instance, +then passes the pipeline to the ``watch()`` method. This instructs the ``watch()`` method +to output only update operations: + +.. literalinclude:: /includes/read/change-streams.cpp + :start-after: start-change-stream-pipeline + :end-before: end-change-stream-pipeline + :language: cpp + :dedent: + +Modify ``watch()`` Behavior +--------------------------- + +You can modify the behavior of the ``watch()`` method by passing an instance +of the ``mongocxx::options::change_stream`` class as a parameter. The following table +describes the fields you can set in a ``mongocxx::options::find`` instance: + +.. list-table:: + :widths: 30 70 + :header-rows: 1 + + * - Field + - Description + + * - ``full_document`` + - | Specifies whether to show the full document after the change, rather + than showing only the changes made to the document. To learn more about + this option, see :ref:`cpp-change-stream-pre-post-image`. + + * - ``full_document_before_change`` + - | Specifies whether to show the full document as it was before the change, rather + than showing only the changes made to the document. To learn more about + this option, see :ref:`cpp-change-stream-pre-post-image`. + + * - ``resume_after`` + - | Instructs ``watch()`` to resume returning changes after the + operation specified in the resume token. + | Each change stream event document includes a resume token as the ``_id`` + field. Pass the entire ``_id`` field of the change event document that + represents the operation you want to resume after. + | ``resume_after`` is mutually exclusive with ``start_after`` and ``start_at_operation_time``. + + * - ``start_after`` + - | Instructs ``watch()`` to start a new change stream after the + operation specified in the resume token. This field allows notifications to + resume after an invalidate event. + | Each change stream event document includes a resume token as the ``_id`` + field. Pass the entire ``_id`` field of the change event document that + represents the operation you want to resume after. + | ``start_after`` is mutually exclusive with ``resume_after`` and ``start_at_operation_time``. + + * - ``start_at_operation_time`` + - | Instructs ``watch()`` to return only events that occur after the + specified timestamp. + | ``start_at_operation_time`` is mutually exclusive with ``resume_after`` and ``start_after``. + + * - ``max_await_time_ms`` + - | Sets the maximum amount of time, in milliseconds, the server waits for new + data changes to report to the change stream cursor before returning an + empty batch. Defaults to 1000 milliseconds. + + * - ``batch_size`` + - | Sets the maximum number of change events to return in each batch of the + response from the MongoDB cluster. + + * - ``collation`` + - | Sets the collation to use for the change stream cursor. + + * - ``comment`` + - | Attaches a comment to the operation. + +.. _cpp-change-stream-pre-post-image: + +Include Pre-Images and Post-Images +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. important:: + + You can enable pre-images and post-images on collections only if your + deployment uses MongoDB v6.0 or later. + +By default, when you perform an operation on a collection, the +corresponding change event includes only the delta of the fields +modified by that operation. To see the full document before or after a +change, specify the ``full_document_before_change`` or the ``full_document`` +fields of a ``mongocxx::options::change_stream`` instance. + +The **pre-image** is the full version of a document *before* a change. To include the +pre-image in the change stream event, set the ``full_document_before_change`` +field to one of the following strings: + +- ``"whenAvailable"``: The change event includes a pre-image of the + modified document for change events only if the pre-image is available. +- ``"required"``: The change event includes a pre-image of the + modified document for change events. If the pre-image is not available, the + driver raises an error. + +The **post-image** is the full version of a document *after* a change. To include the +post-image in the change stream event, set the ``full_document`` field to +one of the following strings: + +- ``"updateLookup"``: The change event includes a copy of the entire changed + document from some time after the change. +- ``"whenAvailable"``: The change event includes a post-image of the + modified document for change events only if the post-image is available. +- ``"required"``: The change event includes a post-image of the + modified document for change events. If the post-image is not available, the + driver raises an error. + +The following example calls the ``watch()`` method on a collection and includes the post-image +of updated documents by setting the ``full_document`` field of a ``mongocxx::options::change_stream`` +instance: + +.. literalinclude:: /includes/read/change-streams.cpp + :start-after: start-change-stream-post-image + :end-before: end-change-stream-post-image + :language: cpp + :dedent: + +With the change stream application running, updating a document in the +``restaurants`` collection by using the :ref:`preceding update example +` prints a change event resembling the following +code: + +.. code-block:: bash + :copyable: false + :emphasize-lines: 3,4,5,6 + + { "_id" : { "_data" : "..." }, "operationType" : "update", "clusterTime" : + { "$timestamp" : { ... } }, "wallTime" : { "$date" : ... }, + "fullDocument" : { "_id" : { "$oid" : "..." }, "address" : { "building" : "202-24", + "coord" : [ -73.925044200000002093, 40.559546199999999772 ], "street" : + "Rockaway Point Boulevard", "zipcode" : "11697" }, "borough" : "Queens", "cuisine" : + "Irish", "grades" : [ ... ], "name" : "Blarney Castle", "restaurant_id" : "40366356" }, + "ns" : { "db" : "sample_restaurants", "coll" : "restaurants" }, "documentKey" : + { "_id" : { "$oid" : "..." } }, "updateDescription" : { "updatedFields" : + { "cuisine" : "Irish" }, "removedFields" : [ ], "truncatedArrays" : [ ] } } + +.. tip:: + + To learn more about pre-images and post-images, see + :manual:`Change Streams with Document Pre- and Post-Images ` + in the {+mdb-server+} manual. + +Additional Information +---------------------- + +To learn more about change streams, see :manual:`Change Streams +` in the {+mdb-server+} manual. + +API Documentation +~~~~~~~~~~~~~~~~~ + +To learn more about any of the methods or types discussed in this +guide, see the following API documentation: + +- `watch() <{+api+}/classmongocxx_1_1v__noabi_1_1collection.html#a1618a354ef5a84299e3680e02636e64e>`__ +- `update_one() <{+api+}/classmongocxx_1_1v__noabi_1_1collection.html#ab7dc140185de1492c52187b19e83d736>`__ +- `mongocxx::pipeline <{+api+}/classmongocxx_1_1v__noabi_1_1pipeline.html>`__ +- `mongocxx::options::change_stream <{+api+}/classmongocxx_1_1v__noabi_1_1options_1_1change__stream.html>`__ \ No newline at end of file diff --git a/source/read/count.txt b/source/read/count.txt new file mode 100644 index 00000000..08d00d6b --- /dev/null +++ b/source/read/count.txt @@ -0,0 +1,230 @@ +.. _cpp-count: + +=============== +Count Documents +=============== + +.. contents:: On this page + :local: + :backlinks: none + :depth: 2 + :class: singlecol + +.. facet:: + :name: genre + :values: reference + +.. meta:: + :keywords: number, amount, estimation, code example + +Overview +--------- + +In this guide, you can learn how to use the {+driver-short+} to retrieve an accurate +and estimated count of the number of documents in a collection. The ``count_documents()`` +method returns the exact number of documents that match a query filter or that exist in +a collection, and the ``estimated_document_count()`` method returns the estimated number +of documents in a collection. + +Sample Data +~~~~~~~~~~~ + +The examples in this guide use the ``companies`` collection in the ``sample_training`` +database from the :atlas:`Atlas sample datasets `. To access this collection +from your C++ application, instantiate a ``mongocxx::client`` that connects to an Atlas +cluster and assign the following values to your ``db`` and ``collection`` variables: + +.. literalinclude:: /includes/read/count.cpp + :language: cpp + :dedent: + :start-after: start-db-coll + :end-before: end-db-coll + +To learn how to create a free MongoDB Atlas cluster and load the sample datasets, see the +:atlas:`Get Started with Atlas ` guide. + +.. _cpp-accurate-count: + +Retrieve an Accurate Count +-------------------------- + +Use the ``count_documents()`` method to count the number of documents that are in a +collection. To count the number of documents that match a specific search +critera, pass a query filter document to the ``count_documents()`` method. + +To learn more about specifying a query, see the :ref:`cpp-specify-query` guide. + +Count All Documents +~~~~~~~~~~~~~~~~~~~ + +To return a count of all documents in the collection, pass an empty filter document to +the ``count_documents()`` method, as shown in the following example: + +.. io-code-block:: + + .. input:: /includes/read/count.cpp + :start-after: start-count-all + :end-before: end-count-all + :language: cpp + :dedent: + + .. output:: + + Number of documents: 9500 + +Count Specific Documents +~~~~~~~~~~~~~~~~~~~~~~~~ + +To return a count of documents that match specific search criteria, pass your query +filter document to the ``count_documents()`` method. + +The following example counts the number of documents that have a ``founded_year`` +value of ``2010``: + +.. io-code-block:: + + .. input:: /includes/read/count.cpp + :start-after: start-count-accurate + :end-before: end-count-accurate + :language: cpp + :dedent: + + .. output:: + + Number of companies founded in 2010: 33 + +Customize Count Behavior +~~~~~~~~~~~~~~~~~~~~~~~~ + +You can modify the behavior of the ``count_documents()`` method by passing +an instance of the ``mongocxx::options::count`` class as a parameter. The following table +describes the fields you can set in a ``mongocxx::options::count`` instance: + +.. list-table:: + :widths: 30 70 + :header-rows: 1 + + * - Field + - Description + + * - ``collation`` + - | The collation to use for the operation. + | **Type**: ``bsoncxx::document::view_or_value`` + + * - ``hint`` + - | The index to use for the operation. + | **Type**: ``mongocxx::hint`` + + * - ``comment`` + - | The comment to attach to the operation. + | **Type**: ``bsoncxx::types::bson_value::view_or_value`` + + * - ``limit`` + - | The maximum number of documents to count. This value must be a positive integer. + | **Type**: ``std::int64_t`` + + * - ``max_time`` + - | The maximum amount of time in milliseconds that the operation can run. + | **Type**: ``std::chrono::milliseconds`` + + * - ``skip`` + - | The number of documents to skip before counting documents. + | **Type**: ``std::int64_t`` + + * - ``read_preference`` + - | The read preference to use for the operation. + | **Type**: ``mongocxx::read_preference`` + +The following example uses the ``count_documents()`` method to count the number of +documents in which the ``number_of_employees`` field has the value ``50`` and instructs the +operation to count a maximum of ``100`` results: + +.. io-code-block:: + + .. input:: /includes/read/count.cpp + :start-after: start-modify-accurate + :end-before: end-modify-accurate + :language: cpp + :dedent: + + .. output:: + + Number of companies with 50 employees: 100 + +.. _cpp-estimated-count: + +Retrieve an Estimated Count +--------------------------- + +You can retrieve an estimate of the number of documents in a collection by calling +the ``estimated_document_count()`` method. The method estimates the amount of +documents based on collection metadata, which might be faster than performing an +accurate count. + +The following example estimates the number of documents in a collection: + +.. io-code-block:: + + .. input:: /includes/read/count.cpp + :start-after: start-count-estimate + :end-before: end-count-estimate + :language: cpp + :dedent: + + .. output:: + + Estimated number of documents: 9500 + +Customize Estimated Count Behavior +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +You can modify the behavior of the ``estimated_document_count()`` method by passing +an instance of the ``mongocxx::options::estimated_document_count`` class as a parameter. +The following table describes the fields you can set in a ``mongocxx::options::estimated_document_count`` +instance: + +.. list-table:: + :widths: 30 70 + :header-rows: 1 + + * - Field + - Description + + * - ``max_time`` + - | The maximum amount of time in milliseconds that the operation can run. + | **Type**: ``std::chrono::milliseconds`` + + * - ``comment`` + - | The comment to attach to the operation. + | **Type**: ``bsoncxx::types::bson_value::view_or_value`` + + * - ``read_preference`` + - | The read preference to use for the operation. + | **Type**: ``mongocxx::read_preference`` + +The following example uses the ``estimated_document_count()`` method to return an +estimate of the number of documents in the collection and instructs the operation +to run for a maximum of ``1000`` milliseconds: + +.. io-code-block:: + + .. input:: /includes/read/count.cpp + :start-after: start-modify-estimate + :end-before: end-modify-estimate + :language: cpp + :dedent: + + .. output:: + + Estimated number of documents: 9500 + +API Documentation +----------------- + +To learn more about any of the methods or types discussed in this +guide, see the following API documentation: + +- `count_documents() <{+api+}/classmongocxx_1_1v__noabi_1_1collection.html#a03c8eb29bfc93cecaefc0ef9773fced7>`__ +- `estimated_document_count() <{+api+}/classmongocxx_1_1v__noabi_1_1collection.html#af143d452f6f4b9b2d3f348cf216e2f41>`__ +- `mongocxx::options::count <{+api+}/classmongocxx_1_1v__noabi_1_1options_1_1count.html>`__ +- `mongocxx::options::estimated_document_count <{+api+}/classmongocxx_1_1v__noabi_1_1options_1_1estimated__document__count.html>`__ \ No newline at end of file diff --git a/source/read/cursor.txt b/source/read/cursor.txt new file mode 100644 index 00000000..3f183572 --- /dev/null +++ b/source/read/cursor.txt @@ -0,0 +1,157 @@ +.. _cpp-cursors: + +========================= +Access Data From a Cursor +========================= + +.. contents:: On this page + :local: + :backlinks: none + :depth: 1 + :class: singlecol + +.. facet:: + :name: genre + :values: reference + +.. meta:: + :keywords: read, results, oplog + +Overview +-------- + +In this guide, you can learn how to access data from a **cursor** by using the +{+driver-short+}. + +A cursor is a mechanism that returns the results of a read operation in iterable +batches. Cursors reduce both memory consumption and network bandwidth usage by holding +only a subset of documents at any given time rather than returning all documents at +once. + +Whenever the {+driver-short+} performs a read operation by using the ``find()`` +method, it returns the matching documents in a ``mongocxx::cursor`` instance. + +Sample Data +~~~~~~~~~~~ + +The examples in this guide use the ``restaurants`` collection in the ``sample_restaurants`` +database from the :atlas:`Atlas sample datasets `. To access this collection +from your C++ application, instantiate a ``mongocxx::client`` that connects to an Atlas cluster +and assign the following values to your ``db`` and ``collection`` variables: + +.. literalinclude:: /includes/read/cursor.cpp + :language: cpp + :dedent: + :start-after: start-db-coll + :end-before: end-db-coll + +To learn how to create a free MongoDB Atlas cluster and load the sample datasets, see the +:atlas:`Get Started with Atlas ` guide. + +.. _cpp-cursors-iterate: + +Retrieve All Cursor Documents +----------------------------- + +To iterate over the contents of a ``mongocxx::cursor`` instance, use a ``for`` loop. + +The following example uses the ``find()`` method to retrieve all documents that have a +``name`` value of ``"Dunkin' Donuts"``. It then prints each document from the cursor returned +by the ``find()`` method: + +.. io-code-block:: + :copyable: + + .. input:: /includes/read/cursor.cpp + :start-after: start-cursor-all + :end-before: end-cursor-all + :language: cpp + :dedent: + + .. output:: + + { "_id" : { "$oid" : "..." }, ... "name" : "Dunkin' Donuts", "restaurant_id" : "40379573" } + { "_id" : { "$oid" : "..." }, ... "name" : "Dunkin' Donuts", "restaurant_id" : "40363098" } + { "_id" : { "$oid" : "..." }, ... "name" : "Dunkin' Donuts", "restaurant_id" : "40395071" } + ... + +Retrieve Documents Individually +------------------------------- + +To retrieve an individual document from a cursor, call the ``begin()`` method on +a ``mongocxx::cursor`` instance. This method returns an instance of ``mongocxx::cursor::iterator`` +that points to the first document in the cursor. + +The following example finds all documents in a collection that have a ``name`` value +of ``"Dunkin' Donuts"``. It then prints the first document from the cursor by calling the +``begin()`` method: + +.. io-code-block:: + :copyable: + + .. input:: /includes/read/cursor.cpp + :start-after: start-cursor-first + :end-before: end-cursor-first + :language: cpp + :dedent: + + .. output:: + + { "_id" : { "$oid" : "..." }, ... "name" : "Dunkin' Donuts", "restaurant_id" : "40379573" } + +Tailable Cursors +---------------- + +When querying on a :manual:`capped collection `, you +can use a **tailable cursor** that remains open after the client exhausts the +results in a cursor. To create a tailable cursor, instantiate a ``mongocxx::options::find`` +object and set its ``cursor_type`` field to ``mongocxx::cursor::type::k_tailable``. Then, +pass your ``mongocxx::options::find`` instance as an argument to the ``find()`` method. + +For example, you can create a capped collection called ``vegetables`` that stores +documents representing vegetables, as shown in the following code: + +.. literalinclude:: /includes/read/cursor.cpp + :language: cpp + :dedent: + :start-after: start-capped-coll + :end-before: end-capped-coll + +The following code uses a tailable cursor to retrieve all documents in the ``vegetables`` +collection. After the cursor is exhausted, it remains open until retrieving three documents: + +.. io-code-block:: + :copyable: + + .. input:: /includes/read/cursor.cpp + :start-after: start-tailable + :end-before: end-tailable + :language: cpp + :dedent: + + .. output:: + + { "_id" : { "$oid" : "..." }, "name" : "cauliflower" } + { "_id" : { "$oid" : "..." }, "name" : "zucchini" } + +If you insert another document into the ``vegetables`` collection, the preceding code prints +the new document and closes the ``while`` loop. + +To learn more about tailable cursors, see the :manual:`Tailable Cursors guide +` in the {+mdb-server+} manual. + +Additional Information +---------------------- + +To learn more about read operations, see the :ref:`cpp-retrieve` guide. + +API Documentation +~~~~~~~~~~~~~~~~~ + +To learn more about any of the methods or types discussed in this +guide, see the following API documentation: + +- `mongocxx::cursor <{+api+}/classmongocxx_1_1v__noabi_1_1cursor>`__ +- `find() <{+api+}/classmongocxx_1_1v__noabi_1_1collection.html#ada76e1596a65c7615e7af7d34a8140d6>`__ +- `begin() <{+api+}/classmongocxx_1_1v__noabi_1_1cursor.html#a85122947e05eb53535c6b62a9c2a1a35>`__ +- `mongocxx::options::find <{+api+}/classmongocxx_1_1v__noabi_1_1options_1_1find.html>`__ \ No newline at end of file diff --git a/source/read/distinct.txt b/source/read/distinct.txt new file mode 100644 index 00000000..c500afe9 --- /dev/null +++ b/source/read/distinct.txt @@ -0,0 +1,160 @@ +.. _cpp-distinct: + +============================== +Retrieve Distinct Field Values +============================== + +.. contents:: On this page + :local: + :backlinks: none + :depth: 2 + :class: singlecol + +.. facet:: + :name: genre + :values: reference + +.. meta:: + :keywords: read, unique, code example + +Overview +-------- + +In this guide, you can learn how to use the {+driver-short+} to retrieve the +distinct values of a specified field across a collection. + +Within a collection, different documents might contain different values for a +single field. For example, one document in a ``restaurants`` collection has a +``borough`` value of ``"Manhattan"``, and another has a ``borough`` value of +``"Queens"``. By using the {+driver-short+}, you can retrieve all the unique values +that a field contains across multiple documents in a collection. + +Sample Data +~~~~~~~~~~~ + +The examples in this guide use the ``restaurants`` collection in the ``sample_restaurants`` +database from the :atlas:`Atlas sample datasets `. To access this collection +from your C++ application, instantiate a ``mongocxx::client`` that connects to an Atlas cluster +and assign the following values to your ``db`` and ``collection`` variables: + +.. literalinclude:: /includes/read/distinct.cpp + :language: cpp + :dedent: + :start-after: start-db-coll + :end-before: end-db-coll + +To learn how to create a free MongoDB Atlas cluster and load the sample datasets, see the +:atlas:`Get Started with Atlas ` guide. + +``distinct()`` Method +--------------------- + +To retrieve the distinct values for a specified field, call the ``distinct()`` +method and pass in the name of the field you want to find distinct values for. + +Retrieve Distinct Values Across a Collection +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The following example retrieves the distinct values of the ``borough`` field in +the ``restaurants`` collection: + +.. io-code-block:: + + .. input:: /includes/read/distinct.cpp + :start-after: start-distinct + :end-before: end-distinct + :language: cpp + :dedent: + + .. output:: + + { "values" : [ "Bronx", "Brooklyn", "Manhattan", "Missing", "Queens", "Staten Island" ], + "ok" : 1.0, "$clusterTime" : { "clusterTime" : { "$timestamp" : { ... } }, + "signature" : { "hash" : { ... }, "keyId" : ... } }, "operationTime" : { "$timestamp" : { ... } } + +The operation returns a cursor that contains a single document. The document includes a list +of distinct ``borough`` field values and metadata about the operation. Although several +documents have the same value in the ``borough`` field, each value appears in the results +only once. + +Retrieve Distinct Values Across Specified Documents +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +You can provide a **query filter** to the ``distinct()`` method to find the distinct +field values across a subset of documents in a collection. A query filter is an expression +that specifies search criteria used to match documents in an operation. For more information +about creating a query filter, see the :ref:`cpp-specify-query` guide. + +The following example retrieves the distinct values of the ``borough`` field for +all documents that have a ``cuisine`` field value of ``"Italian"``: + +.. io-code-block:: + + .. input:: /includes/read/distinct.cpp + :start-after: start-distinct-with-query + :end-before: end-distinct-with-query + :language: cpp + :dedent: + + .. output:: + + { "values" : [ "Bronx", "Brooklyn", "Manhattan", "Queens", "Staten Island" ], + "ok" : 1.0, "$clusterTime" : { "clusterTime" : { "$timestamp" : { ... }, + "signature" : { "hash" : { ... }, "keyId" : ... } }, "operationTime" : { "$timestamp" : { ... } } + +Modify Distinct Behavior +~~~~~~~~~~~~~~~~~~~~~~~~ + +You can modify the behavior of the ``distinct()`` method by passing an instance +of the ``mongocxx::options::distinct`` class as an argument. The following table +describes the fields you can set in a ``mongocxx::options::distinct`` instance: + +.. list-table:: + :widths: 30 70 + :header-rows: 1 + + * - Field + - Description + + * - ``collation`` + - | The collation to use for the operation. + | **Type**: ``bsoncxx::document::view_or_value`` + + * - ``max_time`` + - | The maximum amount of time in milliseconds that the operation can run. + | **Type**: ``std::chrono::milliseconds`` + + * - ``comment`` + - | The comment to attach to the operation. + | **Type**: ``bsoncxx::types::bson_value::view_or_value`` + + * - ``read_preference`` + - | The read preference to use for the operation. + | **Type**: ``mongocxx::read_preference`` + +The following example retrieves the distinct values of the ``name`` field for +all documents that have a ``borough`` field value of ``"Bronx"`` and a +``cuisine`` field value of ``"Pizza"``. It also specifies the ``comment`` field +of an options instance to add a comment to the operation: + +.. io-code-block:: + + .. input:: /includes/read/distinct.cpp + :start-after: start-distinct-with-comment + :end-before: end-distinct-with-comment + :language: cpp + :dedent: + + .. output:: + + { "values" : [ "$1.25 Pizza", "18 East Gunhill Pizza", "2 Bros", "Aenos Pizza", "Alitalia Pizza Restaurant", … ], + "ok" : 1.0, "$clusterTime" : { "clusterTime" : { … }, "signature" : { … }, "keyId" : … } }, "operationTime" : { … } } + +API Documentation +----------------- + +To learn more about any of the methods or types discussed in this +guide, see the following API documentation: + +- `distinct() <{+api+}/classmongocxx_1_1v__noabi_1_1collection.html#a836d42b5ceedb39d064eb5eb3fbb1335>`__ +- `mongocxx::options::distinct <{+api+}/classmongocxx_1_1v__noabi_1_1options_1_1distinct.html>`__ \ No newline at end of file diff --git a/source/read/project.txt b/source/read/project.txt new file mode 100644 index 00000000..7882b50d --- /dev/null +++ b/source/read/project.txt @@ -0,0 +1,161 @@ +.. _cpp-project: + +======================== +Specify Fields To Return +======================== + +.. contents:: On this page + :local: + :backlinks: none + :depth: 2 + :class: singlecol + +.. facet:: + :name: genre + :values: reference + +.. meta:: + :keywords: read, filter, project, select + +Overview +-------- + +In this guide, you can learn how to use the {+driver-short+} to specify which fields +to return from a read operation by using a **projection**. A projection is a document +that specifies which fields MongoDB returns from a query. + +Sample Data +~~~~~~~~~~~ + +The examples in this guide use the ``restaurants`` collection in the ``sample_restaurants`` +database from the :atlas:`Atlas sample datasets `. To access this collection +from your C++ application, instantiate a ``mongocxx::client`` that connects to an Atlas cluster +and assign the following values to your ``db`` and ``collection`` variables: + +.. literalinclude:: /includes/read/project.cpp + :language: cpp + :dedent: + :start-after: start-db-coll + :end-before: end-db-coll + +To learn how to create a free MongoDB Atlas cluster and load the sample datasets, see the +:atlas:`Get Started with Atlas ` guide. + +Projection Types +---------------- + +You can use a projection to specify which fields to include in a return +document, or to specify which fields to exclude. You cannot combine inclusion and +exclusion statements in a single projection, unless you are excluding the +``_id`` field. + +Specify Fields to Include +~~~~~~~~~~~~~~~~~~~~~~~~~ + +To specify the fields to include in the result, create an instance of the +``mongocxx::options::find`` class and set its ``projection`` field. To set +this field, use the following syntax: + +.. code-block:: cpp + + .projection(make_document(kvp("", 1))); + +The following example sets the ``projection`` field of a ``mongocxx::options::find`` +object to return only the ``name``, ``cuisine``, and ``borough`` fields of matching +documents. It then calls the ``find()`` method to find all restaurants in which +the ``name`` field value is ``"Emerald Pub"``, passing the ``mongocxx::options::find`` +object as a parameter to ``find()``: + +.. io-code-block:: + + .. input:: /includes/read/project.cpp + :start-after: start-project-include + :end-before: end-project-include + :language: cpp + :dedent: + :emphasize-lines: 2 + + .. output:: + + { "_id" : { "$oid" : "..." }, "borough" : "Manhattan", "cuisine" : "American", "name" : "Emerald Pub" } + { "_id" : { "$oid" : "..." }, "borough" : "Queens", "cuisine" : "American", "name" : "Emerald Pub" } + +When you use a projection to specify fields to include in the return +document, the ``_id`` field is also included by default. All other fields are +implicitly excluded. To remove the ``_id`` field from the return +document, you must :ref:`explicitly exclude it `. + +.. _cpp-project-remove-id: + +Exclude the ``_id`` Field +~~~~~~~~~~~~~~~~~~~~~~~~~ + +When specifying fields to include, you can also exclude the ``_id`` field from +the returned document. + +The following example performs the same query as the preceding example but +excludes the ``_id`` field from the projection: + +.. io-code-block:: + + .. input:: /includes/read/project.cpp + :start-after: start-project-include-without-id + :end-before: end-project-include-without-id + :language: python + :dedent: + :emphasize-lines: 2 + + .. output:: + + { "borough" : "Manhattan", "cuisine" : "American", "name" : "Emerald Pub" } + { "borough" : "Queens", "cuisine" : "American", "name" : "Emerald Pub" } + +Specify Fields to Exclude +~~~~~~~~~~~~~~~~~~~~~~~~~ + +To specify the fields to exclude in the result, create an instance of the +``mongocxx::options::find`` class and set its ``projection`` field. To set +this field, use the following syntax: + +.. code-block:: cpp + + .projection(make_document(kvp("", 0))); + +The following example sets the ``projection`` field of a ``mongocxx::options::find`` +object to exclude the ``grades`` and ``address`` fields of matching documents. +It then calls the ``find()`` method to find all restaurants in which the ``name`` +field value is ``"Emerald Pub"``, passing the ``mongocxx::options::find`` object +as a parameter to ``find()``: + +.. io-code-block:: + + .. input:: /includes/read/project.cpp + :start-after: start-project-exclude + :end-before: end-project-exclude + :language: cpp + :dedent: + :emphasize-lines: 2 + + .. output:: + + { "_id" : { "$oid" : "..." }, "borough" : "Manhattan", "cuisine" : "American", "name" : "Emerald Pub", "restaurant_id" : "40367329" } + { "_id" : { "$oid" : "..." }, "borough" : "Queens", "cuisine" : "American", "name" : "Emerald Pub", "restaurant_id" : "40668598" } + +When you use a projection to specify which fields to exclude, +any unspecified fields are implicitly included in the return document. + +Additional Information +---------------------- + +To learn more about projections, see the :manual:`Project Fields +` guide in the {+mdb-server+} manual. + +API Documentation +~~~~~~~~~~~~~~~~~ + +To learn more about any of the methods or types discussed in this +guide, see the following API documentation: + +- `find() <{+api+}/classmongocxx_1_1v__noabi_1_1collection.html#ada76e1596a65c7615e7af7d34a8140d6>`__ +- `mongocxx::options::find <{+api+}/classmongocxx_1_1v__noabi_1_1options_1_1find.html>`__ +- `projection <{+api+}/classmongocxx_1_1v__noabi_1_1options_1_1find.html#ae72b241d0825752ebc975eedea20befc>`__ \ No newline at end of file diff --git a/source/read/retrieve.txt b/source/read/retrieve.txt new file mode 100644 index 00000000..e9707e70 --- /dev/null +++ b/source/read/retrieve.txt @@ -0,0 +1,238 @@ +.. _cpp-retrieve: + +============= +Retrieve Data +============= + +.. contents:: On this page + :local: + :backlinks: none + :depth: 2 + :class: singlecol + +.. facet:: + :name: genre + :values: reference + +.. meta:: + :keywords: code examples, read, query, cursor + +Overview +-------- + +In this guide, you can learn how to use the {+driver-short+} to retrieve +data from a MongoDB collection by using **read operations**. You can call the +``find()`` or ``find_one()`` method on a collection to retrieve documents +that match a set of criteria. + +Sample Data +~~~~~~~~~~~ + +The examples in this guide use the ``companies`` collection in the ``sample_training`` +database from the :atlas:`Atlas sample datasets `. To access this collection +from your C++ application, instantiate a ``mongocxx::client`` that connects to an Atlas +cluster and assign the following values to your ``db`` and ``collection`` variables: + +.. literalinclude:: /includes/read/retrieve.cpp + :language: cpp + :dedent: + :start-after: start-db-coll + :end-before: end-db-coll + +To learn how to create a free MongoDB Atlas cluster and load the sample datasets, see the +:atlas:`Get Started with Atlas ` guide. + +.. _cpp-retrieve-find: + +Find Documents +-------------- + +The {+driver-short+} includes two methods for retrieving documents from a collection: +``find_one()`` and ``find()``. +These methods take a **query filter** and return one or more matching documents. +A query filter is an object that specifies the documents you want to retrieve in +your query. + +.. TODO: + To learn more about query filters, see :ref:`cpp-specify-query`. + +.. _cpp-retrieve-find-one: + +Find One Document +~~~~~~~~~~~~~~~~~ + +To find a single document in a collection, call the ``find_one()`` method and pass a query +filter that specifies the criteria of the document you want to find. + +The ``find_one()`` method returns an instance of ``std::optional< bsoncxx::document::value >``. +If the query filter matches a document, the ``optional`` object contains a value of type +``bsoncxx::document::value``. If the query filter does not match any documents, the ``optional`` +object contains no value. + +If the query filter matches more than one document, the ``find_one()`` method returns the *first* +matching document from the retrieved results. + +.. tip:: + + The ``find_one()`` method is useful when you know there's only one matching document + or if you're only interested in the first match. + +The following example uses the ``find_one()`` method to find the first document in which +the ``name`` field has the value ``"LinkedIn"``: + +.. io-code-block:: + + .. input:: /includes/read/retrieve.cpp + :start-after: start-find-one + :end-before: end-find-one + :language: cpp + :dedent: + + .. output:: + + { "_id" : { "$oid" : "52cdef7c4bab8bd675297e0c" }, "name" : "LinkedIn", "permalink" : "linkedin", + "crunchbase_url" : "http://www.crunchbase.com/company/linkedin", "homepage_url" : "http://linkedin.com", + ... + +.. tip:: Sort Order + + The ``find_one()`` method returns the first document in + :manual:`natural order ` + on disk if no sort criteria is specified. + +.. TODO: + To learn more about sorting, see the :ref:`sort guide `. + +.. _cpp-retrieve-find-multiple: + +Find Multiple Documents +~~~~~~~~~~~~~~~~~~~~~~~ + +To find multiple documents in a collection, pass a query filter to the ``find()`` +method that specifies the criteria of the documents you want to retrieve. + +The following example uses the ``find()`` method to find all documents in which +the ``founded_year`` field has the value ``1970``: + +.. literalinclude:: /includes/read/retrieve.cpp + :language: cpp + :dedent: + :start-after: start-find-many + :end-before: end-find-many + +The ``find()`` method returns an instance of ``mongocxx::cursor``, which you can +iterate over to see the matching documents. A cursor is a mechanism that allows an +application to iterate over database results while holding only a subset of them in +memory at a given time. Cursors are useful when your ``find()`` method returns a large +amount of documents. + +You can iterate over the documents in a cursor by using a ``for-in`` loop, as shown in +the following example: + +.. io-code-block:: + + .. input:: /includes/read/retrieve.cpp + :start-after: start-cursor + :end-before: end-cursor + :language: cpp + :dedent: + + .. output:: + + { "_id" : { "$oid" : "52cdef7d4bab8bd675298be4" }, "name" : "Mitsubishi Motors", + "permalink" : "mitsubishi-motors", "crunchbase_url" : "http://www.crunchbase.com/company/mitsubishi-motors", + ... + + { "_id" : { "$oid" : "52cdef7e4bab8bd67529b996" }, "name" : "Western Digital", + "permalink" : "western-digital", "crunchbase_url" : "http://www.crunchbase.com/company/western-digital", + ... + + { "_id" : { "$oid" : "52cdef7e4bab8bd67529b9f1" }, "name" : "Celarayn", "permalink" : "celarayn", + "crunchbase_url" : "http://www.crunchbase.com/company/celarayn", + ... + +.. note:: Find All Documents + + To find all documents in a collection, pass an empty filter + to the ``find()`` method: + + .. code-block:: cpp + + auto cursor = collection.find({}) + +Modify Find Behavior +~~~~~~~~~~~~~~~~~~~~ + +You can modify the behavior of the ``find()`` and ``find_one()`` methods by passing +an instance of the ``mongocxx::options::find`` class as a parameter. The following table +describes some of the fields you can set in a ``mongocxx::options::find`` instance: + +.. list-table:: + :widths: 30 70 + :header-rows: 1 + + * - Field + - Description + + * - ``batch_size`` + - | The number of documents to return per batch. + | **Type**: ``std::int32_t`` + + * - ``collation`` + - | The collation to use for the operation. + | **Type**: ``bsoncxx::document::view_or_value`` + + * - ``comment`` + - | The comment to attach to the operation. + | **Type**: ``bsoncxx::string::view_or_value`` + + * - ``cursor_type`` + - | The type of cursor to use for the operation. + | **Type**: ``cursor::type`` + + * - ``limit`` + - | The maximum number of documents the operation can return. + | **Type**: ``std::int64_t`` + + * - ``skip`` + - | The number of documents to skip before returning results. + | **Type**: ``std::int64_t`` + + * - ``sort`` + - | The order in which the operation returns matching documents. + | **Type**: ``bsoncxx::document::view_or_value`` + +The following example uses the ``find()`` method to find all documents in which +the ``number_of_employees`` field has the value ``1000`` and instructs the +operation to return a maximum of ``5`` results: + +.. literalinclude:: /includes/read/retrieve.cpp + :language: cpp + :dedent: + :start-after: start-modify + :end-before: end-modify + +For a full list of ``mongocxx::options::find`` object fields, see the +`API documentation <{+api+}/classmongocxx_1_1v__noabi_1_1options_1_1find.html>`__. + +.. _cpp-retrieve-additional-information: + +Additional Information +---------------------- + +.. TODO: + To learn more about query filters, see :ref:`cpp-specify-query`. + For runnable code examples of retrieving documents with {+driver-short+}, see :ref:`cpp-read`. + +For more examples that use the ``find()`` and ``find_one()`` methods, see the :ref:`cpp-tutorial-find` +section of the Tutorial page. + +API Documentation +~~~~~~~~~~~~~~~~~ + +To learn more about any of the methods or types discussed in this +guide, see the following API documentation: + +- `find() <{+api+}/classmongocxx_1_1v__noabi_1_1collection.html#ada76e1596a65c7615e7af7d34a8140d6>`__ +- `find_one() <{+api+}/classmongocxx_1_1v__noabi_1_1collection.html#a85f4d18d0d3bb3426109a445196ac587>`__ +- `limit() <{+api+}/classmongocxx_1_1v__noabi_1_1options_1_1find.html#aa8245eed102202a625dab67047903738>`__ \ No newline at end of file diff --git a/source/read/specify-a-query.txt b/source/read/specify-a-query.txt new file mode 100644 index 00000000..11579671 --- /dev/null +++ b/source/read/specify-a-query.txt @@ -0,0 +1,259 @@ +.. _cpp-specify-query: + +=============== +Specify a Query +=============== + +.. contents:: On this page + :local: + :backlinks: none + :depth: 2 + :class: singlecol + +.. facet:: + :name: genre + :values: reference + +.. meta:: + :keywords: expressions, operations, read, write, filter + +Overview +-------- + +In this guide, you can learn how to specify a query by using the {+driver-short+}. + +You can refine the set of documents that a query returns by creating a +**query filter**. A query filter is an expression that specifies the search +criteria that MongoDB uses to match documents in a read or write operation. +In a query filter, you can prompt the driver to search for documents that have +an exact match to your query, or you can compose query filters to express more +complex matching criteria. + +Sample Data +~~~~~~~~~~~ + +The examples in this guide run operations on a collection called +``fruits``, which contains documents representing fruits. The following +code example shows how to create a database and collection, then +insert the sample documents into your collection: + +.. literalinclude:: /includes/read/specify-queries.cpp + :start-after: start-setup + :end-before: end-setup + :language: cpp + :dedent: + :copyable: + +.. include:: /includes/assumes-instance.rst + +Exact Match +----------- + +Literal value queries return documents that have an exact match to your query filter. + +The following example specifies a query filter as a parameter to the ``find()`` +method. The code returns all documents in which the value of the ``color`` field +is ``"yellow"``: + +.. io-code-block:: + :copyable: + + .. input:: /includes/read/specify-queries.cpp + :start-after: start-find-exact + :end-before: end-find-exact + :language: cpp + :dedent: + + .. output:: + + { "_id" : 2, "name" : "bananas", "qty" : 7, "rating" : 4, "color" : "yellow", "type" : [ "cavendish" ] } + { "_id" : 4, "name" : "pineapple", "qty" : 3, "rating" : 5, "color" : "yellow" } + +.. tip:: Find All Documents + + To find all documents in a collection, call the ``find()`` method and pass it an + empty query filter. The following example finds all documents in a + collection: + + .. literalinclude:: /includes/read/specify-queries.cpp + :start-after: start-find-all + :end-before: end-find-all + :language: cpp + :dedent: + :copyable: + +Comparison Operators +-------------------- + +Comparison operators evaluate a document field value against a specified value +in your query filter. The following list defines common comparison operators: + +- ``$gt``: Greater than +- ``$lte``: Less than or Equal +- ``$ne``: Not equal + +To view a full list of comparison operators, see the :manual:`Comparison Query Operators +` guide in the {+mdb-server+} manual. + +The following example specifies a comparison operator in a query filter as a +parameter to the ``find()`` method. The code returns all documents that have a +``rating`` field value greater than ``2``: + +.. io-code-block:: + :copyable: + + .. input:: /includes/read/specify-queries.cpp + :start-after: start-find-comparison + :end-before: end-find-comparison + :language: cpp + :dedent: + + .. output:: + + { "_id" : 1, "name" : "apples", "qty" : 5, "rating" : 3, "color" : "red", "type" : [ "fuji", "honeycrisp" ] } + { "_id" : 2, "name" : "bananas", "qty" : 7, "rating" : 4, "color" : "yellow", "type" : [ "cavendish" ] } + { "_id" : 4, "name" : "pineapples", "qty" : 3, "rating" : 5, "color" : "yellow" } + +Logical Operators +----------------- + +Logical operators match documents by using logic applied to the results of two or +more sets of expressions. The following list describes each logical operator: + +- ``$and``: Returns all documents that match the conditions of *all* clauses +- ``$or``: Returns all documents that match the conditions of *one* clause +- ``$nor``: Returns all documents that *do not* match the conditions of any clause +- ``$not``: Returns all documents that *do not* match the expression + +To learn more about logical operators, see the :manual:`Logical Query Operators +` guide in the {+mdb-server+} manual. + +The following example specifies a logical operator in a query filter as a +parameter to the ``find()`` method. The code returns all documents in which the +``qty`` field value is greater than ``5`` **or** the ``color`` field value is +``"yellow"``: + +.. io-code-block:: + :copyable: + + .. input:: /includes/read/specify-queries.cpp + :start-after: start-find-logical + :end-before: end-find-logical + :language: cpp + :dedent: + + .. output:: + + { "_id" : 2, "name" : "bananas", "qty" : 7, "rating" : 4, "color" : "yellow", "type" : [ "cavendish" ] } + { "_id" : 3, "name" : "oranges", "qty" : 6, "rating" : 2, "type" : [ "naval", "mandarin" ] } + { "_id" : 4, "name" : "pineapples", "qty" : 3, "rating" : 5, "color" : "yellow" } + +Array Operators +--------------- + +Array operators match documents based on the value or quantity of elements in an +array field. The following list describes the available array operators: + +- ``$all``: Returns documents with arrays that contain all elements in the query +- ``$elemMatch``: Returns documents if an element in their array field matches all conditions in the query +- ``$size``: Returns all documents with arrays of a specified size + +To learn more about array operators, see the :manual:`Array Query Operators +` guide in the {+mdb-server+} manual. + +The following example specifies an array operator in a query filter as a +parameter to the ``find()`` method. The code returns all documents in which the +``type`` array field contains ``2`` elements: + +.. io-code-block:: + :copyable: + + .. input:: /includes/read/specify-queries.cpp + :start-after: start-find-array + :end-before: end-find-array + :language: cpp + :dedent: + + .. output:: + + { "_id" : 1, "name" : "apples", "qty" : 5, "rating" : 3, "color" : "red", "type" : [ "fuji", "honeycrisp" ] } + { "_id" : 3, "name" : "oranges", "qty" : 6, "rating" : 2, "type" : [ "naval", "mandarin" ] } + +Element Operators +----------------- + +Element operators query data based on the presence or type of a field. + +To learn more about element operators, see the :manual:`Element Query Operators +` guide in the {+mdb-server+} manual. + +The following example specifies an element operator in a query filter as a +parameter to the ``find()`` method. The code returns all documents that have a +``color`` field: + +.. io-code-block:: + :copyable: + + .. input:: /includes/read/specify-queries.cpp + :start-after: start-find-element + :end-before: end-find-element + :language: cpp + :dedent: + + .. output:: + + { "_id" : 1, "name" : "apples", "qty" : 5, "rating" : 3, "color" : "red", "type" : [ "fuji", "honeycrisp" ] } + { "_id" : 2, "name" : "bananas", "qty" : 7, "rating" : 4, "color" : "yellow", "type" : [ "cavendish" ] } + { "_id" : 4, "name" : "pineapples", "qty" : 3, "rating" : 5, "color" : "yellow" } + +Evaluation Operators +-------------------- + +Evaluation operators return data based on evaluations of either individual +fields or the entire collection's documents. + +The following list describes common evaluation operators: + +- ``$text``: Performs a text search on the documents +- ``$regex``: Returns documents that match a specified regular expression +- ``$mod``: Performs a modulo operation on the value of a field and + returns documents where the remainder is a specified value + +To view a full list of evaluation operators, see the :manual:`Evaluation Query Operators +` guide in the {+mdb-server+} manual. + +The following example specifies an evaluation operator in a query filter as a +parameter to the ``find()`` method. The code uses a regular expression to return +all documents in which the ``name`` field value has at least two consecutive +``"p"`` characters: + +.. io-code-block:: + :copyable: + + .. input:: /includes/read/specify-queries.cpp + :start-after: start-find-evaluation + :end-before: end-find-evaluation + :language: cpp + :dedent: + + .. output:: + + { "_id" : 1, "name" : "apples", "qty" : 5, "rating" : 3, "color" : "red", "type" : [ "fuji", "honeycrisp" ] } + { "_id" : 4, "name" : "pineapples", "qty" : 3, "rating" : 5, "color" : "yellow" } + +Additional Information +---------------------- + +To learn more about querying documents, see the :manual:`Query Documents +` guide in the {+mdb-server+} manual. + +To learn more about retrieving documents with the {+driver-short+}, see the +:ref:`cpp-retrieve` guide. + +API Documentation +~~~~~~~~~~~~~~~~~ + +To learn more about any of the methods or types discussed in this +guide, see the following API documentation: + +- `find() <{+api+}/classmongocxx_1_1v__noabi_1_1collection.html#adcbb56b329ffbc28e517ba7a2e111908>`__ \ No newline at end of file diff --git a/source/read/specify-documents-to-return.txt b/source/read/specify-documents-to-return.txt new file mode 100644 index 00000000..27f5ed76 --- /dev/null +++ b/source/read/specify-documents-to-return.txt @@ -0,0 +1,196 @@ +.. _cpp-specify-documents-to-return: + +=========================== +Specify Documents to Return +=========================== + +.. contents:: On this page + :local: + :backlinks: none + :depth: 2 + :class: singlecol + +.. facet:: + :name: genre + :values: reference + +.. meta:: + :keywords: read, paginate, pagination, order, code example + +Overview +-------- + +In this guide, you can learn how to specify which documents to return from a read +operation by using the following methods: + +- :ref:`mongocxx::options::find::limit() `: Specifies the maximum number of documents + to return from a query. +- :ref:`mongocxx::options::find::sort() `: Specifies the sort order for the returned documents. +- :ref:`mongocxx::options::find::skip() `: Specifies the number of documents to skip before + returning query results. + +Sample Data +~~~~~~~~~~~ + +The examples in this guide use the ``restaurants`` collection in the ``sample_restaurants`` +database from the :atlas:`Atlas sample datasets `. To access this collection +from your C++ application, instantiate a ``mongocxx::client`` that connects to an Atlas cluster +and assign the following values to your ``db`` and ``collection`` variables: + +.. literalinclude:: /includes/read/limit-skip-sort.cpp + :language: cpp + :dedent: + :start-after: start-db-coll + :end-before: end-db-coll + +To learn how to create a free MongoDB Atlas cluster and load the sample datasets, see +the :atlas:`Get Started with Atlas ` guide. + +.. _cpp-return-documents-limit: + +Limit +----- + +To specify the maximum number of documents returned from a read operation, create +an instance of the ``mongocxx::options::find`` class and set its ``limit`` field. +Then, pass your ``mongocxx::options::find`` instance as an argument to the +``find()`` method. + +The following example finds all restaurants that have a ``cuisine`` field value +of ``"Italian"`` and limits the results to ``5`` documents: + +.. io-code-block:: + + .. input:: /includes/read/limit-skip-sort.cpp + :start-after: start-limit-method + :end-before: end-limit-method + :language: cpp + :dedent: + + .. output:: + + { "_id" : { "$oid" : "..." }, ..., "name" : "Philadelphia Grille Express", "restaurant_id" : "40364305" } + { "_id" : { "$oid" : "..." }, ..., "name" : "Isle Of Capri Restaurant", "restaurant_id" : "40364373" } + { "_id" : { "$oid" : "..." }, ..., "name" : "Marchis Restaurant", "restaurant_id" : "40364668" } + { "_id" : { "$oid" : "..." }, ..., "name" : "Crystal Room", "restaurant_id" : "40365013" } + { "_id" : { "$oid" : "..." }, ..., "name" : "Forlinis Restaurant", "restaurant_id" : "40365098" } + +.. tip:: + + The preceding example returns the first five documents matched by the query + according to their :manual:`natural order ` + in the database. The following section describes how to return the documents + in a specified order. + +.. _cpp-return-documents-sort: + +Sort +---- + +To return documents in a specified order, create a document that includes +the field to sort the results by and the sort direction. A value of ``1`` sorts +values from lowest to highest, and a value of ``-1`` sorts them from highest to +lowest. Then, call the ``mongocxx::options::find::sort()`` method on a +``mongocxx::options::find`` instance and pass this document as an argument. + +The following example returns all documents that have a ``cuisine`` value of ``"Italian"``, +sorted in ascending order of ``name`` field values: + +.. io-code-block:: + + .. input:: /includes/read/limit-skip-sort.cpp + :start-after: start-sort-method + :end-before: end-sort-method + :language: cpp + :dedent: + + .. output:: + + { "_id" : { "$oid" : "..." }, ..., "name" : "(Lewis Drug Store) Locanda Vini E Olii", "restaurant_id" : "40804423" } + { "_id" : { "$oid" : "..." }, ..., "name" : "101 Restaurant And Bar", "restaurant_id" : "40560108" } + { "_id" : { "$oid" : "..." }, ..., "name" : "44 Sw Ristorante & Bar", "restaurant_id" : "40698807" } + ... + { "_id" : { "$oid" : "..." }, ..., "name" : "Zucchero E Pomodori", "restaurant_id" : "41189590" } + +.. _cpp-return-documents-skip: + +Skip +---- + +To skip a specified number of documents before returning your query results, create +an instance of the ``mongocxx::options::find`` class and set its ``skip`` field. +Then, pass your ``mongocxx::options::find`` instance as an argument to the +``find()`` method. + +The following example returns all documents that have a ``borough`` field value +of ``"Manhattan"`` and skips the first ``10`` documents: + +.. io-code-block:: + + .. input:: /includes/read/limit-skip-sort.cpp + :start-after: start-skip-method + :end-before: end-skip-method + :language: cpp + :dedent: + + .. output:: + + { "_id" : { "$oid" : "..." }, ..., "name" : "Cafe Metro", "restaurant_id" : "40363298" } + { "_id" : { "$oid" : "..." }, ..., "name" : "Lexler Deli", "restaurant_id" : "40363426" } + { "_id" : { "$oid" : "..." }, ..., "name" : "Domino'S Pizza", "restaurant_id" : "40363644" } + ... + +.. _cpp-return-documents-combine: + +Combine Limit, Sort, and Skip +----------------------------- + +You can set the ``limit``, ``sort``, and ``skip`` fields of a single +``mongocxx::options::find`` instance. This allows you to set a maximum +number of sorted documents to return, skipping a specified number of +documents before returning. + +The following example returns ``5`` documents that have a ``cuisine`` value of +``"Italian"``. The results are sorted in ascending order by ``name`` field value, +skipping the first ``10`` documents: + +.. io-code-block:: + + .. input:: /includes/read/limit-skip-sort.cpp + :start-after: start-limit-sort-skip + :end-before: end-limit-sort-skip + :language: cpp + :dedent: + + .. output:: + + { "_id" : { "$oid" : "..." }, ..., "name" : "Acqua", "restaurant_id" : "40871070" } + { "_id" : { "$oid" : "..." }, ..., "name" : "Acqua Restaurant", "restaurant_id" : "41591488" } + { "_id" : { "$oid" : "..." }, ..., "name" : "Acqua Santa", "restaurant_id" : "40735858" } + { "_id" : { "$oid" : "..." }, ..., "name" : "Acquista Trattoria", "restaurant_id" : "40813992" } + { "_id" : { "$oid" : "..." }, ..., "name" : "Acquolina Catering", "restaurant_id" : "41381423" } + +.. note:: + + The order in which you call these methods doesn't change the documents + that are returned. The driver automatically reorders the calls to perform the + sort operation first, the skip operation next, and then the limit operation. + +Additional Information +---------------------- + +For more information about retrieving documents, see the :ref:`cpp-retrieve` guide. + +For more information about specifying a query, see the :ref:`cpp-specify-query` guide. + +API Documentation +~~~~~~~~~~~~~~~~~ + +To learn more about any of the methods or types discussed in this +guide, see the following API documentation: + +- `mongocxx::collection::find() <{+api+}/classmongocxx_1_1v__noabi_1_1collection.html#ada76e1596a65c7615e7af7d34a8140d6>`__ +- `mongocxx::options::find <{+api+}/classmongocxx_1_1v__noabi_1_1options_1_1find.html>`__ +- `mongocxx::options::find::limit() <{+api+}/classmongocxx_1_1v__noabi_1_1options_1_1find.html#a3eb2bdc65a762bb31cbb64aa3ff2522a>`__ +- `mongocxx::options::find::sort() <{+api+}/classmongocxx_1_1v__noabi_1_1options_1_1find.html#a39e497bf0c084d9ddb1ccc68edee4b3a>`__ +- `mongocxx::options::find::skip() <{+api+}/classmongocxx_1_1v__noabi_1_1options_1_1find.html#a7f5688e726d8c460d016e5007a47e001>`__ diff --git a/source/security.txt b/source/security.txt new file mode 100644 index 00000000..c6e14962 --- /dev/null +++ b/source/security.txt @@ -0,0 +1,233 @@ +.. _cpp-security: + +================ +Secure Your Data +================ + +.. contents:: On this page + :local: + :backlinks: none + :depth: 2 + :class: singlecol + +.. facet:: + :name: genre + :values: reference + +.. meta:: + :keywords: ldap, authorize, ecs, aws, authenticate + :description: Learn how to use {+driver-short+} to secure your data. + +.. toctree:: + :titlesonly: + :maxdepth: 1 + + /security/authentication + /security/enterprise-authentication + /security/in-use-encryption + +Overview +-------- + +MongoDB supports multiple mechanisms that you can use to authenticate your application. +This page contains code examples that demonstrate each of these mechanisms. + +.. tip:: + + To learn more about any of the authentication mechanisms on this page, see the + :ref:`cpp-auth` and :ref:`cpp-enterprise-auth` pages. + +To use an authentication example from this page, copy the code example into the +:ref:`sample application ` or your own application. +Be sure to replace all placeholders in the code examples, such as ````, with +the relevant values for your MongoDB deployment. + +.. _cpp-auth-sample: + +.. include:: /includes/usage-examples/sample-app-intro.rst + +.. literalinclude:: /includes/usage-examples/connect-sample-app.cpp + :language: cpp + :copyable: true + :linenos: + :emphasize-lines: 16-18 + +SCRAM-SHA-256 +------------- + +The following code shows how to create a connection URI to authenticate by using +the ``SCRAM-SHA-256`` authentication mechanism: + +.. literalinclude:: /includes/authentication.cpp + :language: cpp + :copyable: true + :start-after: // start-scram-sha-256 + :end-before: // end-scram-sha-256 + +To learn more about SCRAM-SHA-256 authentication, see :ref:`cpp-scram-sha-256` in +the Authentication guide. + +SCRAM-SHA-1 +----------- + +The following code shows how to create a connection URI to authenticate by using +the ``SCRAM-SHA-1`` authentication mechanism: + +.. literalinclude:: /includes/authentication.cpp + :language: cpp + :copyable: true + :start-after: // start-scram-sha-1 + :end-before: // end-scram-sha-1 + +To learn more about SCRAM-SHA-1 authentication, see :ref:`cpp-scram-sha-1` in +the Authentication guide. + +MONGODB X.509 +------------- + +The following code shows how to create a connection URI to authenticate by using +the ``X.509`` authentication mechanism: + +.. literalinclude:: /includes/authentication.cpp + :language: cpp + :copyable: true + :start-after: // start-x509 + :end-before: // end-x509 + +To learn more about X.509 authentication, see :ref:`cpp-x509` in +the Authentication guide. + +MONGODB-AWS +----------- + +The following sections show how to connect to MongoDB by using the ``MONGODB-AWS`` +authentication mechanism. When you use the ``MONGODB-AWS`` mechanism, the {+driver-short+} attempts to +retrieve your AWS credentials from the following sources, in the order listed: + +1. Named parameters passed to the Connection URI +#. Environment variables +#. AWS EKS AssumeRoleWithWebIdentity request +#. ECS container metadata +#. EC2 instance metadata + +Each section shows how to create the connection URI to authenticate with +``MONGODB-AWS`` when retrieving your AWS credentials from the specified source. + +To learn more about authenticating with AWS, see +:ref:`cpp-mongo-aws` in the Authentication guide. + +Connection URI +~~~~~~~~~~~~~~ + +The following code shows how to create a connection URI that includes AWS credentials to +authenticate with ``MONGODB-AWS``: + +.. literalinclude:: /includes/authentication.cpp + :language: cpp + :copyable: true + :start-after: // start-aws-connection-uri + :end-before: // end-aws-connection-uri + +Environment Variables +~~~~~~~~~~~~~~~~~~~~~ + +The following code shows how to create a connection URI to +authenticate with ``MONGODB-AWS`` when obtaining credentials from environment +variables. Ensure you have your environment variables specified before running +this code. + +.. literalinclude:: /includes/authentication.cpp + :language: cpp + :copyable: true + :start-after: // start-aws-environment + :end-before: // end-aws-environment + +To learn more about authenticating with AWS by using environment +variables, see :ref:`cpp-mongo-aws-environment`. + +AssumeRoleWithWebIdentity Request +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The following code shows how to create a connection URI to +authenticate with ``MONGODB-AWS`` when obtaining credentials from an +``AssumeRoleWithWebIdentity`` request. Ensure that an AWS config file exists in your +environment and is configured with the ``AWS_WEB_IDENTITY_TOKEN_FILE`` +and ``AWS_ROLE_ARN`` environment variables. + +.. literalinclude:: /includes/authentication.cpp + :language: cpp + :copyable: true + :start-after: // start-aws-environment + :end-before: // end-aws-environment + +To learn more about authenticating with AWS by using an +``AssumeRoleWithWebIdentity`` request, see :ref:`cpp-mongo-aws-assume-role`. + +ECS Metadata +~~~~~~~~~~~~ + +The following code shows how to create a connection URI to +authenticate with ``MONGODB-AWS`` when obtaining credentials from ECS metadata. +Ensure that you specify the URI of the ECS endpoint in an environment variable called +``AWS_CONTAINER_CREDENTIALS_RELATIVE_URI``. + +.. literalinclude:: /includes/authentication.cpp + :language: cpp + :copyable: true + :start-after: // start-aws-environment + :end-before: // end-aws-environment + +To learn more about authenticating with AWS by using ECS metadata, see :ref:`cpp-mongo-aws-ecs`. + +EC2 Instance Metadata +~~~~~~~~~~~~~~~~~~~~~ + +The following code shows how to create a connection URI to +authenticate with ``MONGODB-AWS`` when obtaining credentials from EC2 instance +metadata. Ensure that you configure your EC2 instance with your temporary credentials. + +.. literalinclude:: /includes/authentication.cpp + :language: cpp + :copyable: true + :start-after: // start-aws-environment + :end-before: // end-aws-environment + +To learn more about authenticating with AWS by using EC2 instance metadata, see :ref:`cpp-mongo-aws-ec2`. + +Kerberos +-------- + +.. note:: MongoDB Enterprise Only + + Kerberos authentication is available only in MongoDB Enterprise. + +The following code shows how to create a connection URI to +authenticate with Kerberos: + +.. literalinclude:: /includes/authentication.cpp + :language: cpp + :copyable: true + :start-after: // start-kerberos + :end-before: // end-kerberos + +To learn more about authenticating with Kerberos, see +:ref:`cpp-kerberos` in the Enterprise Authentication guide. + +PLAIN SASL +---------- + +.. note:: MongoDB Enterprise Only + + PLAIN SASL authentication is available only in MongoDB Enterprise. + +The following code shows how to create a connection URI to +authenticate with PLAIN SASL: + +.. literalinclude:: /includes/authentication.cpp + :language: cpp + :copyable: true + :start-after: // start-plain + :end-before: // end-plain + +To learn more about authenticating with PLAIN SASL, see +:ref:`cpp-plain` in the Enterprise Authentication guide. diff --git a/source/security/authentication.txt b/source/security/authentication.txt new file mode 100644 index 00000000..83ff27f4 --- /dev/null +++ b/source/security/authentication.txt @@ -0,0 +1,282 @@ +.. _cpp-auth: + +========================= +Authentication Mechanisms +========================= + +.. contents:: On this page + :local: + :backlinks: none + :depth: 2 + :class: singlecol + +.. facet:: + :name: genre + :values: reference + +.. meta:: + :keywords: authorize, secure, connect + +Overview +-------- + +This guide describes the mechanisms you can use in the {+driver-short+} to authenticate +users. + +.. _cpp-scram-sha-256: + +SCRAM-SHA-256 +------------- + +SCRAM-SHA-256, as defined by `RFC 7677 `__, +is the default authentication mechanism on MongoDB deployments +running MongoDB v4.0 or later. + +To authenticate with this mechanism, set the following connection options: + +- ``username``: The username to authenticate. +- ``password``: The password to authenticate. +- ``authSource``: The MongoDB database to authenticate against. By default, + {+driver-short+} authenticates against the database in the connection + URI, if you include one. If you don't, it authenticates against the ``admin`` database. +- ``authMechanism``: Set to ``"SCRAM-SHA-256"``. + +You can set these options in the connection string when creating a +``mongocxx::client`` object, as shown in the following example: + +.. literalinclude:: /includes/authentication.cpp + :language: cpp + :copyable: true + :start-after: // start-scram-sha-256 + :end-before: // end-scram-sha-256 + +.. _cpp-scram-sha-1: + +SCRAM-SHA-1 +----------- + +SCRAM-SHA-1, as defined by `RFC 5802 `__, +is the default authentication mechanism on MongoDB deployments +running MongoDB v3.6. + +To authenticate with this mechanism, set the following connection options: + +- ``username``: The username to authenticate. +- ``password``: The password to authenticate. +- ``authSource``: The MongoDB database to authenticate against. By default, + {+driver-short+} authenticates against the ``admin`` database. +- ``authMechanism``: Set to ``"SCRAM-SHA-1"``. + +You can set these options in the connection string when creating a +``mongocxx::client`` object, as shown in the following example: + +.. literalinclude:: /includes/authentication.cpp + :language: cpp + :copyable: true + :start-after: // start-scram-sha-1 + :end-before: // end-scram-sha-1 + +.. _cpp-x509: + +MONGODB X.509 +------------- + +If you enable TLS, during the TLS handshake, the {+driver-short+} can present an X.509 +client certificate to MongoDB to prove its identity. The ``MONGODB-X509`` authentication +mechanism uses this certificate to authenticate the client. + +To authenticate with this mechanism, set the following connection options: + +- ``tls``: Set to ``True``. +- ``tlsCertificateKeyFile``: The file path of the ``.pem`` file that contains your + client certificate and private key. +- ``authMechanism``: Set to ``"MONGODB-X509"``. + +You can set these options in the connection string when creating a +``mongocxx::client`` object, as shown in the following example: + +.. literalinclude:: /includes/authentication.cpp + :language: cpp + :copyable: true + :start-after: // start-x509 + :end-before: // end-x509 + +.. TODO: To learn more about enabling TLS, see :ref:`cpp-tls`. + +.. _cpp-mongo-aws: + +MONGODB-AWS +----------- + +.. important:: + + The MONGODB-AWS authentication mechanism requires MongoDB v4.4 or later. + +The ``MONGODB-AWS`` authentication mechanism uses AWS IAM (Amazon Web Services Identity and +Access Management) or AWS Lambda credentials to authenticate your application. +To authenticate using this mechanism, first create a user with an associated Amazon Resource Name (ARN) on +the ``$external`` database, then specify the ``MONGODB-AWS`` authMechanism in the +URI. + +When you use the ``MONGODB-AWS`` mechanism, the {+driver-short+} attempts to +retrieve your AWS credentials from the following sources, in the order listed: + +1. Named parameters passed to the Connection URI +#. Environment variables +#. AWS EKS AssumeRoleWithWebIdentity request +#. ECS container metadata +#. EC2 instance metadata + +The following sections describe how to use the {+driver-short+} to retrieve credentials from +these sources and use them to authenticate your application. + +Connection URI +~~~~~~~~~~~~~~ + +First, the {+driver-short+} checks whether you passed AWS credentials to the +``MongoClient`` constructor as part of the connection +URI. To pass your credentials in the connection URI, set the following connection +options: + +- ``username``: The AWS IAM access key ID to authenticate. +- ``password``: The AWS IAM secret access key. +- ``authMechanism``: Set to ``"MONGODB-AWS"``. + +You can set these options in the connection string when creating a +``mongocxx::client`` object, as shown in the following example: + +.. literalinclude:: /includes/authentication.cpp + :language: cpp + :copyable: true + :start-after: // start-aws-connection-uri + :end-before: // end-aws-connection-uri + +You can also include an AWS session token by passing it into the +``authMechanismProperties`` parameter: + +.. literalinclude:: /includes/authentication.cpp + :language: cpp + :copyable: true + :start-after: // start-aws-connection-uri-session + :end-before: // end-aws-connection-uri-session + +.. _cpp-mongo-aws-environment: + +Environment Variables +~~~~~~~~~~~~~~~~~~~~~ + +If you don't provide a username and password when you construct your ``MongoClient`` +object, the {+driver-short+} tries to retrieve AWS credentials from the following +environment variables: + +- ``AWS_ACCESS_KEY_ID`` +- ``AWS_SECRET_ACCESS_KEY`` +- ``AWS_SESSION_TOKEN`` (optional) + +To use these environment variables to authenticate your application, first set them to the +AWS IAM values needed for authentication, as shown in the following code +example: + +.. code-block:: sh + + export AWS_ACCESS_KEY_ID= + export AWS_SECRET_ACCESS_KEY= + export AWS_SESSION_TOKEN= + +After you set these environment variables, set the ``authMechanism`` +parameter in your connection URI to ``"MONGODB-AWS"``, as shown in the +following example: + +.. literalinclude:: /includes/authentication.cpp + :language: cpp + :copyable: true + :start-after: // start-aws-environment + :end-before: // end-aws-environment + +.. _cpp-mongo-aws-assume-role: + +AssumeRoleWithWebIdentity Request +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +If your application authenticates users for your EKS cluster from an OpenID Connect (OIDC) +identity provider, the {+driver-short+} can make an ``AssumeRoleWithWebIdentity`` request +to exchange the OIDC token for temporary AWS credentials for your application. + +To authenticate with temporary AWS IAM credentials returned by an +``AssumeRoleWithWebIdentity`` request, ensure that the AWS config file exists in your +environment and is configured with the ``AWS_WEB_IDENTITY_TOKEN_FILE`` +and ``AWS_ROLE_ARN`` environment variables. To learn how to create and configure +an AWS config file, see `Configuration `__ +in the AWS documentation. + +After you configure your environment for an ``AssumeRoleWithWebIdentity`` request, +set the ``authMechanism`` parameter in your connection URI to ``"MONGODB-AWS"``, +as shown in the following example: + +.. literalinclude:: /includes/authentication.cpp + :language: cpp + :copyable: true + :start-after: // start-aws-environment + :end-before: // end-aws-environment + +For more information about using an ``AssumeRoleWithWebIdentity`` request to +authenticate your application, see the following AWS documentation: + +- `AssumeRoleWithWebIdentity `__ +- `Authenticating users for your cluster from an OpenID Connect identity provider `__ + +.. _cpp-mongo-aws-ecs: + +ECS Metadata +~~~~~~~~~~~~ + +If your application runs in an Elastic Container Service (ECS) container, +the {+driver-short+} can automatically retrieve temporary AWS credentials from an +ECS endpoint. To do so, specify the URI of the ECS endpoint in an environment variable called +``AWS_CONTAINER_CREDENTIALS_RELATIVE_URI``, as shown in the following example: + +.. code-block:: sh + + export AWS_CONTAINER_CREDENTIALS_RELATIVE_URI= + +After you set the environment variable, set the ``authMechanism`` +parameter in your connection URI to ``"MONGODB-AWS"``, as shown in the +following example: + +.. literalinclude:: /includes/authentication.cpp + :language: cpp + :copyable: true + :start-after: // start-aws-environment + :end-before: // end-aws-environment + +.. _cpp-mongo-aws-ec2: + +EC2 Instance Metadata +~~~~~~~~~~~~~~~~~~~~~ + +The {+driver-short+} can automatically retrieve temporary AWS credentials from an +Amazon Elastic Cloud Compute (EC2) instance. To use temporary credentials from +within an EC2 instance, set the ``authMechanism`` parameter in your connection +URI to ``"MONGODB-AWS"``, as shown in the following example: + +.. literalinclude:: /includes/authentication.cpp + :language: cpp + :copyable: true + :start-after: // start-aws-environment + :end-before: // end-aws-environment + +.. note:: + + If you set any of the environment variables from the preceding AWS authentication + methods, the {+driver-short+} attempts to retrieve credentials by using those + methods before attempting to retrieve them from an EC2 instance. To attempt + to retrieve credentials only from an EC2 instance, ensure that the + environment variables are not set. + +API Documentation +----------------- + +To learn more about creating a ``mongocxx::client`` object in {+driver-short+}, +see the following API documentation: + +- `mongocxx::client <{+api+}/classmongocxx_1_1v__noabi_1_1client.html>`__ diff --git a/source/security/enterprise-authentication.txt b/source/security/enterprise-authentication.txt new file mode 100644 index 00000000..fb660935 --- /dev/null +++ b/source/security/enterprise-authentication.txt @@ -0,0 +1,127 @@ +.. _cpp-enterprise-auth: + +==================================== +Enterprise Authentication Mechanisms +==================================== + +.. contents:: On this page + :local: + :backlinks: none + :depth: 2 + :class: singlecol + +.. facet:: + :name: genre + :values: reference + +.. meta:: + :keywords: ldap, tls, security + +Overview +-------- + +MongoDB Enterprise Edition includes authentication mechanisms that aren't +available in MongoDB Community Edition. +In this guide, you can learn how to authenticate to MongoDB by using these +authentication mechanisms. To learn about the other authentication mechanisms available +in MongoDB, see :ref:``. + +.. _cpp-kerberos: + +Kerberos +-------- + +The Generic Security Services API (GSSAPI) provides an interface for Kerberos +authentication. + +.. note:: + + To authenticate with GSSAPI, you must build the MongoDB C driver with SASL support. + If you are building the driver from source, you can enable SASL support with + the ``ENABLE_SASL`` ``cmake`` option. + +Complete the following steps to authenticate with GSSAPI: + +.. procedure:: + :style: connected + + .. step:: Obtain a Ticket-Granting Ticket + + On Unix environments, you must first run the ``kinit`` command to obtain and cache + an initial ticket-granting ticket. If you're running a Windows environment, + you can skip ahead to the next step. + + The following example uses the + ``kinit`` command to obtain a ticket-granting ticket for the principal + ``mongodbuser@EXAMPLE.COM``. It then uses the ``klist`` + command to display the principal and ticket in the credentials cache. + + .. code-block:: sh + :copyable: false + + $ kinit mongodbuser@EXAMPLE.COM + mongodbuser@EXAMPLE.COM's Password: + $ klist + Credentials cache: FILE:/tmp/krb5cc_1000 + Principal: mongodbuser@EXAMPLE.COM + + Issued Expires Principal + Feb 9 13:48:51 2013 Feb 9 23:48:51 2013 krbtgt/mongodbuser@EXAMPLE.COM + + .. step:: Set the Connection Options + + Next, set the following connection options: + + - ``username``: The Kerbos principal to authenticate. + - ``authMechanism``: Set to ``"GSSAPI"``. + - ``authMechanismProperties``: Optional. By default, MongoDB uses ``mongodb`` as + the authentication service name. To specify a different service name, set + this option to ``"SERVICE_NAME:"``. + + You can set these options through parameters in your connection URI, as shown in + the following example: + + .. literalinclude:: /includes/authentication.cpp + :language: cpp + :copyable: true + :start-after: // start-kerberos + :end-before: // end-kerberos + + .. note:: + + You must replace the ``@`` symbol in the principal with ``%40``, as shown + in the preceding example. + +.. _cpp-plain: + +PLAIN SASL +---------- + +The PLAIN Simple Authentication and Security Layer (SASL), as defined +by `RFC 4616 `__, is a username-password +authentication mechanism often used with TLS or another encryption layer. + +.. important:: + + PLAIN SASL is a clear-text authentication mechanism. We strongly recommend that you + use TLS/SSL with certificate validation when using PLAIN SASL to authenticate to MongoDB. + +.. TODO: To learn more about how to enable TLS for your connection, see :ref:``. + +To authenticate with SASL, set the ``authMechanism`` connection option to ``PLAIN``. +You can set this option through a parameter in your connection string, as shown +in the following example: + +.. literalinclude:: /includes/authentication.cpp + :language: cpp + :copyable: true + :start-after: // start-plain + :end-before: // end-plain + +API Documentation +----------------- + +To learn more about creating a ``mongocxx::client`` object in {+driver-short+}, +see the following API documentation: + +- `mongocxx::client <{+api+}/classmongocxx_1_1v__noabi_1_1client.html>`__ \ No newline at end of file diff --git a/source/security/in-use-encryption.txt b/source/security/in-use-encryption.txt new file mode 100644 index 00000000..568c7e6d --- /dev/null +++ b/source/security/in-use-encryption.txt @@ -0,0 +1,101 @@ +.. _cpp-in-use-encryption: + +================= +In-Use Encryption +================= + +.. contents:: On this page + :local: + :backlinks: none + :depth: 1 + :class: singlecol + +.. facet:: + :name: genre + :values: reference + +.. meta:: + :keywords: qe, csfle, field level encryption + +Overview +-------- + +You can use the {+driver-short+} to encrypt specific document fields by using a +set of features called **in-use encryption**. In-use encryption allows +your application to encrypt data *before* sending it to MongoDB +and query documents with encrypted fields. + +In-use encryption prevents unauthorized users from viewing plaintext +data as it is sent to MongoDB or while it is in an encrypted database. To +enable in-use encryption in an application and authorize it to decrypt +data, you must create encryption keys that only your application can +access. Only applications that have access to your encryption +keys can access the decrypted, plaintext data. If an attacker gains +access to the database, they can see only the encrypted ciphertext data +because they lack access to the encryption keys. + +You can use in-use encryption to encrypt fields in your MongoDB +documents that contain the following types of sensitive data: + +- Credit card numbers +- Addresses +- Health information +- Financial information +- Any other sensitive or personally identifiable information (PII) + +MongoDB offers the following features to enable in-use encryption: + +- :ref:`Queryable Encryption ` +- :ref:`Client-side Field Level Encryption ` + +.. _subsection-qe: + +Queryable Encryption +-------------------- + +Queryable Encryption is the next-generation in-use encryption feature, +first introduced as a preview feature in {+mdb-server+} version 6.0 and +as a generally available (GA) feature in MongoDB 7.0. Queryable +Encryption supports searching encrypted fields for equality and encrypts +each value uniquely. + +.. important:: Preview Feature Incompatible with MongoDB 7.0 + + The implementation of Queryable Encryption in MongoDB 6.0 is incompatible with + the GA version introduced in MongoDB 7.0. The Queryable Encryption preview + feature is no longer supported. + +To learn more about Queryable Encryption, see :manual:`Queryable +Encryption ` in the MongoDB Server manual. + +.. _subsection-csfle: + +Client-side Field Level Encryption +---------------------------------- + +Client-side Field Level Encryption (CSFLE) was introduced in MongoDB +Server version 4.2 and supports searching encrypted fields for equality. +CSFLE differs from Queryable Encryption in that you can select either a +deterministic or random encryption algorithm to encrypt fields. You can only +query encrypted fields that use a deterministic encryption algorithm when +using CSFLE. When you use a random encryption algorithm to encrypt +fields in CSFLE, they can be decrypted, but you cannot perform equality +queries on those fields. When you use Queryable Encryption, you cannot +specify the encryption algorithm, but you can query all encrypted +fields. + +When you deterministically encrypt a value, the same input value +produces the same output value. While deterministic encryption allows +you to perform queries on those encrypted fields, encrypted data with +low cardinality is susceptible to code breaking by frequency analysis. + +.. tip:: + + To learn more about these concepts, see the following Wikipedia + entries: + + - :wikipedia:`Cardinality ` + - :wikipedia:`Frequency Analysis ` + +To learn more about CSFLE, see :manual:`CSFLE ` in the +Server manual. \ No newline at end of file diff --git a/source/tutorial.txt b/source/tutorial.txt index edf556f9..1566bf4c 100644 --- a/source/tutorial.txt +++ b/source/tutorial.txt @@ -211,6 +211,8 @@ If the value in the name field is not a string and you do not include a type guard as seen in the preceding example, this code will throw an instance of `bsoncxx::exception <{+api+}/classbsoncxx_1_1v__noabi_1_1exception>`__. +.. _cpp-tutorial-insert: + Insert Documents ---------------- @@ -284,6 +286,8 @@ instance. assert(doc0_id.type() == bsoncxx::type::k_oid); assert(doc1_id.type() == bsoncxx::type::k_oid); +.. _cpp-tutorial-find: + Query the Collection --------------------- diff --git a/source/upgrade.txt b/source/upgrade.txt new file mode 100644 index 00000000..223bb5c1 --- /dev/null +++ b/source/upgrade.txt @@ -0,0 +1,102 @@ +.. _cpp-upgrade: + +======================= +Upgrade Driver Versions +======================= + +.. contents:: On this page + :local: + :backlinks: none + :depth: 1 + :class: singlecol + +.. facet:: + :name: genre + :values: reference + +.. meta:: + :keywords: compatibility, backwards compatibility + +Overview +-------- + +This page describes the changes you must make to your application +when you upgrade to a new version of the {+driver-short+}. + +Before you upgrade, perform the following actions: + +- Ensure the new {+driver-short+} version is compatible with the {+mdb-server+} versions + your application connects to and the C++ standard version your + application compiles with. For version compatibility information, see the + :ref:`{+driver-short+} Compatibility ` + page. +- Address any breaking changes between the driver version + your application is using and your planned upgrade version in the + :ref:`Breaking Changes ` section. + +.. tip:: + + To ensure compatibility across {+mdb-server+} versions when + upgrading driver versions, use the + :ref:`{+stable-api+} `. + +.. _cpp-breaking-changes: + +Breaking Changes +---------------- + +.. note:: + + The {+driver-short+} follows :wikipedia:`semantic versioning. ` + The driver may break build system or package compatibility in any release. + Patch releases may revert accidental API breaking changes. + + For more information, see :ref:``. + +A breaking change is a change of a convention or a behavior starting in a specific +version of the driver. This type of change may prevent your application from working +properly if not addressed before upgrading the driver. + +The breaking changes in this section are categorized by the driver version that introduced +them. When upgrading driver versions, address all the breaking changes between the current +and upgrade versions. + +.. example:: Upgrading from Version 3.0 + + If you're upgrading the {+driver-short+} from version 3.0 to version 3.10, + address all breaking changes listed for versions 3.1 to 3.10, if any. + +.. _version-3.10-breaking-changes: + +Version 3.10 Breaking Changes +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +This driver version introduces the following breaking changes: + +- Drops support for ``find_package(libbsoncxx)`` and ``find_package(libmongocxx)``. + Use ``find_package(bsoncxx)`` and ``find_package(mongocxx)`` + instead. +- Drops support for the ``LIBBSONCXX_*`` and ``LIBMONGOCXX_*`` CMake variables + provided by the legacy CMake package config files. Use the ``mongo::bsoncxx_*`` and + ``mongo::mongocxx_*`` CMake targets instead. +- Removes the experimental C++ standard library (``BSONCXX_POLY_USE_STD_EXPERIMENTAL``) as a + polyfill option. + +.. _version-3.9-breaking-changes: + +Version 3.9 Breaking Changes +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +This driver version introduces the following breaking changes: + +- Removes support for exported targets from the CMake project build tree +- Drops support for macOS 10.14, macOS 10.15, and Ubuntu 14.04 +- Requires MongoDB C Driver v1.25.0 or later +- Requires CMake v3.15 or later + +Version 3.8 and Earlier +~~~~~~~~~~~~~~~~~~~~~~~ + +For driver versions 3.8 and earlier, see the +release notes and associated JIRA tickets for each release +on `GitHub. `__ \ No newline at end of file diff --git a/source/whats-new.txt b/source/whats-new.txt new file mode 100644 index 00000000..98656466 --- /dev/null +++ b/source/whats-new.txt @@ -0,0 +1,174 @@ +.. _cpp-whats-new: + +========== +What's New +========== + +.. contents:: On this page + :local: + :backlinks: none + :depth: 2 + :class: singlecol + +.. facet:: + :name: genre + :values: reference + +.. meta:: + :keywords: update, new feature, deprecation, upgrade, driver + +Overview +-------- + +Learn what's new in: + +* :ref:`Version 3.10 ` +* :ref:`Version 3.9 ` + +Types of Breaking Changes +~~~~~~~~~~~~~~~~~~~~~~~~~ + +New versions of the {+driver-short+} can introduce the following types of breaking changes: + +- **API** changes concern the API of the {+driver-short+} libraries. These changes are + accompanied by an API major version bump. You might need to edit C++ source code + in your project to address these changes. + + .. example:: + + - Removes the declaration of function ``v1::func()``. (The definition is still provided for ABI compatibility.) + - Removes the inline function ``v_noabi::func()``. + - Removes ``v_noabi::func()``. + - Changes the redeclaration of ``bsoncxx::foo`` from ``v1::foo`` to ``v2::foo``. + To continue using the old interface, qualify ``bsoncxx::foo`` as ``bsoncxx::v1::foo``. + +- **ABI** changes concern the ABI of the {+driver-short+} libraries. These changes are + accompanied by an ABI version bump, and may also be accompanied by an API major version + bump. You might need to rebuild your project or edit your C++ source code to address + these changes. + + ABI stability is **not** supported for symbols corresponding to entities declared in + the ``v_noabi`` namespace. Breaking changes for such symbols are not necessarily + accompanied by an ABI version bump. + + .. example:: + + - Removes the exported symbol ``v_noabi::func()``. + - Removes the exported symbol ``v1::func()``. + - Removes the exported symbols for ``v1::type``. + +- **Build system** changes concern the build system or packaging of the {+driver-short+} + libraries. These changes are not necessarily accompanied by either an API major version + bump or an ABI version bump. + To address these changes, you might need to modify your build system configurations or + update your project's package or dependency management settings. You might also need to + modify or rebuild your C++ source code. + + .. example:: + + - Removes the ``ENABLE_FOO`` configuration variable. + - Changes the default value of the ``ENABLE_BAR`` configuration variable from + ``OFF`` to ``ON``. + - Drops support for platform A, compiler B, or architecture C. + +.. _upcoming-breaking-changes: + +.. _version-3.10: + +What's New in 3.10 +------------------ + +.. warning:: Build System Breaking Changes + + The v3.10 driver introduces the following breaking changes to the build system: + + - Drops support for calling ``find_package(libbsoncxx)`` and ``find_package(libmongocxx)``. + Use ``find_package(bsoncxx)`` and ``find_package(mongocxx)`` + instead. + - Drops support for the ``LIBBSONCXX_*`` and ``LIBMONGOCXX_*`` CMake variables + provided by the legacy CMake package config files. Use the ``mongo::bsoncxx_*`` and + ``mongo::mongocxx_*`` CMake targets instead. + - Removes the ``BSONCXX_POLY_USE_STD_EXPERIMENTAL`` CMake option and drops support for selecting the experimental C++ standard library as a polyfill option. + +The v3.10.0 driver release includes the following new features: + +- Adds forward headers that provide non-defining declarations of ``bsoncxx`` and + ``mongocxx`` class types. The driver does not support user-defined forward declarations + of any library entity. To obtain the declaration or definition of a library entity, + always include the corresponding header. +- The CMake option ``ENABLE_BSONCXX_USE_POLY_IMPLS`` allows selecting + ``bsoncxx`` implementations of C++17 polyfills by default when no polyfill library is + requested. This option is ``OFF`` by default. +- The CMake option ``BSONCXX_POLY_USE_IMPLS`` allows selecting ``bsoncxx`` implementations + of C++17 polyfills instead of external libraries or the C++ standard library. This + option is ``OFF`` by default. +- The ``bsoncxx::v_noabi`` and ``mongocxx::v_noabi`` namespaces are no longer declared inline. + Root namespace declarations are still supported and expected to remain equivalent to + their prior definitions. For example, ``bsoncxx::document`` is still equivalent to + ``bsoncxx::v_noabi::document``, and ``mongocxx::client`` is still equivalent to + ``mongocxx::v_noabi::client``. +- By default, when library filenames are compiled with MSVC (as detected by CMake's ``MSVC`` + variable), they are embedded with an ABI tag string. These strings are similar to + the following: + + .. code-block:: bash + + bsoncxx-v_noabi-rhs-x64-v142-md.lib + + To disable this behavior, set ``ENABLE_ABI_TAG_IN_LIBRARY_FILENAMES=OFF`` as part of + your CMake configuration. + + The ABI tag string can also be embedded in pkg-config metadata filenames, similar to the + following: + + .. code-block:: bash + + libbsoncxx-v_noabi-rhs-x64-v142-md.pc + + To enable this behavior, set ``ENABLE_ABI_TAG_IN_LIBRARY_FILENAMES=ON`` and + ``ENABLE_ABI_TAG_IN_PKGCONFIG_FILENAMES=ON`` as part of your CMake configuration. + +To learn more about this release, see the +`v3.10 Release Notes `__ +on GitHub. + +.. _version-3.9: + +What's New in 3.9 +----------------- + +.. warning:: Build System Breaking Changes + + The v3.9 driver introduces the following breaking changes: + + - Removes support for exported targets from the CMake project build tree + - Drops support for macOS 10.14, macOS 10.15, and Ubuntu 14.04 + - Requires MongoDB C Driver v1.25.0 or later + - Requires CMake v3.15 or later to support the ``FetchContent`` module + +The v3.9 driver release includes the following new features: + +- The {+driver-short+} container image is now available on + `Docker hub `__. +- The driver automatically downloads the MongoDB C Driver dependency if you don't provide + it. +- The driver no longer builds tests as part of the ``all`` target. To build tests, + set ``BUILD_TESTING=ON`` as part of your CMake configuration. +- The driver uses the ``FetchContent`` module to download and build the + `MNMLSTC Core `__ polyfill library, if not + provided by the system, instead of the ``ExternalProject`` module. It also does not + patch ``include`` directives in MNMLSTC Core headers. +- Adds the CMake option ``MONGOCXX_OVERRIDE_DEFAULT_INSTALL_PREFIX``. If this option is set to + ``TRUE``, the ``CMAKE_INSTALL_PREFIX`` option defaults to the build directory. + The default value of this option is ``TRUE``. +- Adds an API for managing + :atlas:`Atlas Search indexes `. +- Adds the ``VERSIONINFO`` resource to ``bsoncxx.dll`` and ``mongocxx.dll``. +- Explicitly documents that throwing an exception from an APM callback is undefined behavior. +- Does not prematurely install MNMLSTC Core headers during the CMake build step. +- Requires that a MongoDB C Driver CMake package is found via ``find_dependency()`` for all + installed {+driver-short+} package configurations. + +To learn more about this release, see the +`v3.9 Release Notes `__ +on GitHub. \ No newline at end of file diff --git a/source/work-with-indexes.txt b/source/work-with-indexes.txt new file mode 100644 index 00000000..dba61ed3 --- /dev/null +++ b/source/work-with-indexes.txt @@ -0,0 +1,162 @@ +.. _cpp-work-with-indexes: + +================= +Work with Indexes +================= + +.. contents:: On this page + :local: + :backlinks: none + :depth: 2 + :class: singlecol + +.. facet:: + :name: genre + :values: reference + +.. meta:: + :keywords: query, optimization, efficiency + +Overview +-------- + +In this guide, you can learn how to use **indexes** with the {+driver-short+}. +Indexes can improve the efficiency of queries and add additional functionality +to querying and storing documents. + +Without indexes, MongoDB must scan every document in a collection to find the +documents that match each query. These collection scans are +slow and can negatively affect the performance of your application. However, if an +appropriate index exists for a query, MongoDB can use the index to limit the +documents it must inspect. + +Operational Considerations +~~~~~~~~~~~~~~~~~~~~~~~~~~ + +To improve query performance, build indexes on fields that appear often in +your application's queries and operations that return sorted results. Each +index that you add consumes disk space and memory when active, so we recommend +that you track index memory and disk usage for capacity planning. In addition, +when a write operation updates an indexed field, MongoDB also updates any related +index. + +Because MongoDB supports dynamic schemas, applications can query against fields +whose names are not known in advance or are arbitrary. MongoDB 4.2 introduced +:manual:`wildcard indexes ` to help support these +queries. Wildcard indexes are not designed to replace workload-based index +planning. + +For more information about designing your data model and choosing indexes appropriate for your application, see the +:manual:`Data Modeling and Indexes ` guide +in the {+mdb-server+} manual. + +Sample Data +~~~~~~~~~~~ + +The examples in this guide use the ``sample_mflix.movies`` collection +from the :atlas:`Atlas sample datasets `. To learn how to create a +free MongoDB Atlas cluster and load the sample datasets, see +:ref:``. + +Create an Index +--------------- + +MongoDB supports several different index types to support querying your data. +The following sections describe the most common index types and provide sample +code for creating each index type. + +.. _cpp-single-field-index: + +Single-Field Indexes +~~~~~~~~~~~~~~~~~~~~ + +:manual:`Single-field indexes ` are indexes with a +reference to a single field within a collection's +documents. They improve single-field query and sort performance, and support +:manual:`TTL (time to live) indexes `, which +automatically remove documents from a collection after a certain amount of time +or at a specific clock time. You can specify the sort order of the index entries +by specifying ``1`` for ascending or ``-1`` for descending. + +.. note:: + + The ``_id_`` index is an example of a single-field index. This index is + automatically created on the ``_id`` field when a new collection is created. + +The following example creates a single-field index in ascending order on the ``title`` field: + +.. literalinclude:: /includes/indexes/indexes.cpp + :start-after: start-index-single + :end-before: end-index-single + :language: cpp + :copyable: + +To learn more about single-field indexes, see :manual:`Single Field Indexes +` in the {+mdb-server+} manual. + +.. _cpp-indexes-remove: + +Remove an Index +--------------- + +You can remove any unused index except the default unique index on the +``_id`` field. + +The following sections show how to remove a single index and how to remove all +indexes in a collection. + +Remove a Single Index +~~~~~~~~~~~~~~~~~~~~~ + +Pass an instance of an index or the index name to the ``drop_one()`` method to +remove an index from a collection. + +The following example removes an index with the name ``"title_1"`` from the ``movies`` +collection: + +.. literalinclude:: /includes/indexes/indexes.cpp + :language: cpp + :start-after: start-remove-index + :end-before: end-remove-index + +.. note:: + + You cannot remove a single field from a compound text index. You must + drop the entire index and create a new one to update the indexed + fields. + +Remove All Indexes +~~~~~~~~~~~~~~~~~~ + +Starting with MongoDB 4.2, you can drop all indexes by calling the +``drop_all()`` method on the index view in your collection: + +.. literalinclude:: /includes/indexes/indexes.cpp + :language: cpp + :start-after: start-remove-all-indexes + :end-before: end-remove-all-indexes + +For earlier versions of MongoDB, pass ``"*"`` as a parameter to your call to +``drop_one()`` on the index view in your collection: + +.. literalinclude:: /includes/indexes/indexes.cpp + :language: cpp + :start-after: start-remove-all-wildcard + :end-before: end-remove-all-wildcard + +Additional Information +---------------------- + +To learn more about indexes in MongoDB, see the :manual:`Indexes ` +guide in the {+mdb-server+} manual. + +API Documentation +~~~~~~~~~~~~~~~~~ + +To learn more about any of the methods or types discussed in this +guide, see the following API documentation: + +- `create_index() <{+api+}/classmongocxx_1_1v__noabi_1_1collection.html#a39cf05fd8da3a7993929c8bfd3de9b46>`__ +- `drop_one() <{+api+}/classmongocxx_1_1v__noabi_1_1index__view.html#a1779a23bd9565cf295cc2479b6e5981a>`__ +- `drop_all() <{+api+}/classmongocxx_1_1v__noabi_1_1index__view.html#a2fc4f2778ce800076368f026fd2649d8>`__ +- `indexes() <{+api+}/classmongocxx_1_1v__noabi_1_1collection.html#aac9843f8a560d39b85ef24a651d66e3b>`__ \ No newline at end of file diff --git a/source/write.txt b/source/write.txt new file mode 100644 index 00000000..8a29dd3e --- /dev/null +++ b/source/write.txt @@ -0,0 +1,163 @@ +.. _cpp-write: + +===================== +Write Data to MongoDB +===================== + +.. contents:: On this page + :local: + :backlinks: none + :depth: 2 + :class: singlecol + +.. facet:: + :name: genre + :values: reference + +.. meta:: + :description: Learn how to use the C++ driver to write data to MongoDB. + :keywords: usage examples, save, crud, create, code example + +.. toctree:: + :titlesonly: + :maxdepth: 1 + + /write/insert + /write/update + /write/delete + /write/bulk-write + +.. TODO: + /write/replace + /write/gridfs + +Overview +-------- + +On this page, you can see copyable code examples that show common +{+driver-short+} methods for writing data to MongoDB. + +.. tip:: + + To learn more about any of the methods shown on this page, see the link + provided in each section. + +To use an example from this page, copy the code example into the +:ref:`sample application ` or your own application. +Be sure to replace all placeholders, such as ````, with +the relevant values for your MongoDB deployment. + +.. _cpp-write-sample: + +.. include:: /includes/usage-examples/sample-app-intro.rst + +.. literalinclude:: /includes/usage-examples/sample-app.cpp + :language: cpp + :dedent: + :linenos: + :emphasize-lines: 23-25 + +Insert One +---------- + +The following code shows how to insert a single document into a collection: + +.. literalinclude:: /includes/usage-examples/write-code-examples.cpp + :start-after: start-insert-one + :end-before: end-insert-one + :language: cpp + :dedent: + +To learn more about the ``insert_one()`` method, see the :ref:`Insert Documents +` guide. + +Insert Multiple +--------------- + +The following code shows how to insert multiple documents into a collection: + +.. literalinclude:: /includes/usage-examples/write-code-examples.cpp + :start-after: start-insert-multiple + :end-before: end-insert-multiple + :language: cpp + :dedent: + +To learn more about the ``insert_many()`` method, see the :ref:`Insert Documents +` guide. + +Update One +---------- + +The following code shows how to update a single document in a collection by creating +or editing a field: + +.. literalinclude:: /includes/usage-examples/write-code-examples.cpp + :start-after: start-update-one + :end-before: end-update-one + :language: cpp + :dedent: + +To learn more about the ``update_one()`` method, see the +:ref:`Update Documents ` guide. + +Update Multiple +--------------- + +The following code shows how to update multiple documents in a collection by creating +or editing a field: + +.. literalinclude:: /includes/usage-examples/write-code-examples.cpp + :start-after: start-update-multiple + :end-before: end-update-multiple + :language: cpp + :dedent: + +To learn more about the ``update_many()`` method, see the +:ref:`Update Documents ` guide. + +.. TODO: + Replace One + ----------- + +Delete One +---------- + +The following code shows how to delete a single document in a collection: + +.. literalinclude:: /includes/usage-examples/write-code-examples.cpp + :start-after: start-delete-one + :end-before: end-delete-one + :language: cpp + :dedent: + +To learn more about the ``delete_one()`` method, see the +:ref:`Delete Documents ` guide. + +Delete Multiple +--------------- + +The following code shows how to delete multiple documents in a collection: + +.. literalinclude:: /includes/usage-examples/write-code-examples.cpp + :start-after: start-delete-multiple + :end-before: end-delete-multiple + :language: cpp + :dedent: + +To learn more about the ``delete_many()`` method, see the +:ref:`Delete Documents ` guide. + +Bulk Write +---------- + +The following code shows how to perform multiple write operations in a single bulk +operation: + +.. literalinclude:: /includes/usage-examples/write-code-examples.cpp + :start-after: start-bulk-write + :end-before: end-bulk-write + :language: cpp + :dedent: + +To learn more about the ``create_bulk_write()`` method, see the +:ref:`Bulk Write ` guide. diff --git a/source/write/bulk-write.txt b/source/write/bulk-write.txt new file mode 100644 index 00000000..05b24111 --- /dev/null +++ b/source/write/bulk-write.txt @@ -0,0 +1,368 @@ +.. _cpp-bulk-write: + +===================== +Bulk Write Operations +===================== + +.. contents:: On this page + :local: + :backlinks: none + :depth: 2 + :class: singlecol + +.. facet:: + :name: genre + :values: reference + +.. meta:: + :keywords: insert, update, replace, code example + +Overview +-------- + +In this guide, you can learn how to perform multiple write operations +in a single database call by using **bulk write operations**. + +Consider a scenario in which you want to insert a document into a collection, +update multiple other documents, then delete a document. If you use +individual methods, each operation requires its own database call. Instead, +you can use a bulk operation to reduce the number of calls to the database. + +Sample Data +~~~~~~~~~~~ + +The examples in this guide use the ``restaurants`` collection in the ``sample_restaurants`` +database from the :atlas:`Atlas sample datasets `. To access this collection +from your C++ application, instantiate a ``mongocxx::client`` that connects to an Atlas cluster +and assign the following values to your ``db`` and ``collection`` variables: + +.. literalinclude:: /includes/write/bulk-write.cpp + :start-after: start-db-coll + :end-before: end-db-coll + :language: cpp + :dedent: + +To learn how to create a free MongoDB Atlas cluster and load the sample datasets, see the +:atlas:`Get Started with Atlas ` guide. + +.. _cpp-bulk-start-operation: + +Create a Bulk Write Instance +---------------------------- + +Before running a bulk write operation, call the ``create_bulk_write()`` method on +a collection. This method returns an instance of the ``mongocxx::bulk_write`` +class that you can use to store instructions about which types of bulk writes to +perform. + +The following example calls the ``create_bulk_write()`` method on the ``restaurants`` +collection: + +.. literalinclude:: /includes/write/bulk-write.cpp + :start-after: start-create-bulk-write + :end-before: end-create-bulk-write + :language: cpp + :dedent: + +You can then append write models to your ``mongocxx::bulk_write`` instance to define +the bulk operation. For more information, see the following :ref:`cpp-bulk-define-write-models` +section. + +.. _cpp-bulk-define-write-models: + +Define the Write Operations +--------------------------- + +For each write operation you want to perform, create an instance of one of +the following model classes: + +- ``mongocxx::model::insert_one`` +- ``mongocxx::model::update_one`` +- ``mongocxx::model::update_many`` +- ``mongocxx::model::replace_one`` +- ``mongocxx::model::delete_one`` +- ``mongocxx::model::delete_many`` + +Then, append each write model to the ``mongocxx::bulk_write`` instance returned +by the ``create_bulk_write()`` method. + +The following sections show how to create and use instances of the preceding +write model classes. + +.. _cpp-bulk-insert-model: + +Insert Operations +~~~~~~~~~~~~~~~~~ + +To perform an insert operation, create an instance of the ``mongocxx::model::insert_one`` +class and specify the document you want to insert. Then, append the model instance +to an instance of the ``mongocxx::bulk_write`` class. + +The following example creates an instance of ``mongocxx::model::insert_one`` and appends +it to a ``mongocxx::bulk_write`` instance called ``bulk``: + +.. literalinclude:: /includes/write/bulk-write.cpp + :start-after: start-bulk-insert-one + :end-before: end-bulk-insert-one + :language: cpp + :dedent: + +To insert multiple documents, create an instance of ``mongocxx::model::insert_one`` +for each document. + +.. _cpp-bulk-update-model: + +Update Operations +~~~~~~~~~~~~~~~~~ + +To update a document, create an instance of ``mongocxx::model::update_one``. This model +instructs the driver to update *the first* document that matches your query filter. Then, +append the model instance to an instance of the ``mongocxx::bulk_write`` class. + +Pass the following arguments to the ``mongocxx::model::update_one`` model: + +- **Query filter** document, which specifies the criteria used to match documents + in your collection. +- **Update** document, which specifies the kind of update to perform. For more information + about update operations, see the :manual:`Field Update Operators + ` guide in the {+mdb-server+} manual. + +The following example creates an instance of ``mongocxx::model::update_one`` and appends +it to a ``mongocxx::bulk_write`` instance called ``bulk``: + +.. literalinclude:: /includes/write/bulk-write.cpp + :start-after: start-bulk-update-one + :end-before: end-bulk-update-one + :language: cpp + :dedent: + +To update multiple documents, create an instance of ``mongocxx::model::update_many`` +and pass in the same arguments. This model instructs the driver to update *all* documents +that match your query filter. + +The following example creates an instance of ``mongocxx::model::update_many`` and appends +it to ``bulk``: + +.. literalinclude:: /includes/write/bulk-write.cpp + :start-after: start-bulk-update-many + :end-before: end-bulk-update-many + :language: cpp + :dedent: + +.. _cpp-bulk-replace-model: + +Replace Operations +~~~~~~~~~~~~~~~~~~ + +A replace operation removes all fields and values of a specified document and +replaces them with new ones. To perform a replace operation, create an instance +of the ``mongocxx::model::replace_one`` class and pass it a query filter and +the fields and values you want to store in the matching document. Then, append +the model instance to an instance of the ``mongocxx::bulk_write`` class. + +The following example creates an instance of ``mongocxx::model::replace_one`` and appends +it to a ``mongocxx::bulk_write`` instance called ``bulk``: + +.. literalinclude:: /includes/write/bulk-write.cpp + :start-after: start-bulk-replace-one + :end-before: end-bulk-replace-one + :language: cpp + :dedent: + +To replace multiple documents, you must create a new instance of ``mongocxx::model::replace_one`` +for each document. + +.. _cpp-bulk-delete-model: + +Delete Operations +~~~~~~~~~~~~~~~~~ + +To delete a document, create an instance of the ``mongocxx::model::delete_one`` class and +pass in a query filter specifying the document you want to delete. This model instructs +the driver to delete only *the first* document that matches your query filter. Then, append +the model instance to an instance of the ``mongocxx::bulk_write`` class. + +The following example creates an instance of ``mongocxx::model::delete_one`` and appends +it to a ``mongocxx::bulk_write`` instance called ``bulk``: + +.. literalinclude:: /includes/write/bulk-write.cpp + :start-after: start-bulk-delete-one + :end-before: end-bulk-delete-one + :language: cpp + :dedent: + +To delete multiple documents, create an instance of the ``mongocxx::model::delete_many`` +class and pass in a query filter specifying the document you want to delete. This model +instructs the driver to delete *all* documents that match your query filter. + +The following example creates an instance of ``mongocxx::model::delete_many`` and appends +it to ``bulk``: + +.. literalinclude:: /includes/write/bulk-write.cpp + :start-after: start-bulk-delete-many + :end-before: end-bulk-delete-many + :language: cpp + :dedent: + +Run the Bulk Operation +---------------------- + +To run a bulk operation, call the ``execute()`` method on an instance of the +``mongocxx::bulk_write`` class that contains your write models. By default, the +``execute()`` method runs the operations in the order they're appended to the +``mongocxx::bulk_write`` instance. + +The following example performs the :ref:`insert `, +:ref:`update `, :ref:`replace `, +and :ref:`delete ` operations specified in the preceding +sections of this guide by appending each corresponding write model to an instance +of ``mongocxx::bulk_write`` and calling the ``execute()`` method. Then, it prints +the number of modified documents: + +.. io-code-block:: + + .. input:: /includes/write/bulk-write.cpp + :start-after: start-bulk-run + :end-before: end-bulk-run + :language: cpp + :dedent: + :emphasize-lines: 30 + + .. output:: + + Modified documents: 2 + +If any of the write operations fail, the {+driver-short+} raises a +``mongocxx::bulk_write_exception`` and does not perform any further operations. + +.. tip:: + + To learn more about the ``modified_count()`` function, see the :ref:`cpp-bulk-return-value` + section of this guide. + +Customize Bulk Write Operations +------------------------------- + +You can modify the behavior of the ``create_bulk_write()`` method by passing +an instance of the ``mongocxx::options::bulk_write`` class as a parameter. The following +table describes the fields you can set in a ``mongocxx::options::bulk_write`` +instance: + +.. list-table:: + :widths: 30 70 + :header-rows: 1 + + * - Field + - Description + + * - ``ordered`` + - | If ``true``, the driver performs the write operations in the order + provided. If an error occurs, the remaining operations are not + attempted. + | + | If ``false``, the driver performs the operations in an + arbitrary order and attempts to perform all operations. + | Defaults to ``true``. + + * - ``bypass_document_validation`` + - | Specifies whether the operation bypasses document-level validation. For more + information, see :manual:`Schema + Validation ` in the MongoDB + Server manual. + | Defaults to ``false``. + + * - ``write_concern`` + - | Specifies the write concern for the bulk operation. For more information, see + :manual:`Write Concern ` in the {+mdb-server+} manual. + + * - ``comment`` + - | Attaches a comment to the operation. For more information, see the :manual:`delete command + fields ` guide in the + {+mdb-server+} manual. + + * - ``let`` + - | Specifies a document with a list of values to improve operation readability. Values + must be constant or closed expressions that don't reference document fields. For more + information, see the :manual:`let statement + ` in the {+mdb-server+} manual. + +The following example calls the ``create_bulk_write()`` method from the +:ref:`cpp-bulk-start-operation` example on this page, but sets the ``ordered`` field +of a ``mongocxx::options::bulk_write`` instance to ``false``: + +.. literalinclude:: /includes/write/bulk-write.cpp + :start-after: start-bulk-write-unordered + :end-before: end-bulk-write-unordered + :language: cpp + :dedent: + +If any of the write operations in an unordered bulk write fail, the {+driver-short+} +reports the errors only after attempting all operations. + +.. note:: + + Unordered bulk operations do not guarantee order of execution. The order can + differ from the way you list them to optimize the runtime. + +.. _cpp-bulk-return-value: + +Return Value +------------ + +The ``execute()`` method returns an instance of the ``mongocxx::result::bulk_write`` class. +The ``mongocxx::result::bulk_write`` class contains the following member functions: + +.. list-table:: + :widths: 30 70 + :header-rows: 1 + + * - Function + - Description + + * - ``deleted_count()`` + - | Returns the number of documents deleted, if any. + + * - ``inserted_count()`` + - | Returns the number of documents inserted, if any. + + * - ``matched_count()`` + - | Returns the number of documents matched for an update, if applicable. + + * - ``modified_count()`` + - | Returns the number of documents modified, if any. + + * - ``upserted_count()`` + - | Returns the number of documents upserted, if any. + + * - ``upserted_ids()`` + - | Returns a map of the operation's index to the ``_id`` of the upserted documents, if + applicable. + +Additional Information +---------------------- + +To learn how to perform individual write operations, see the following guides: + +- :ref:`cpp-write-insert` +- :ref:`cpp-write-update` +- :ref:`cpp-write-delete` + +.. TODO: + - :ref:`cpp-write-replace` + +API Documentation +~~~~~~~~~~~~~~~~~ + +To learn more about any of the methods or types discussed in this +guide, see the following API documentation: + +- `create_bulk_write() <{+api+}/classmongocxx_1_1v__noabi_1_1collection.html#abbf0932175201384cc902c80740adfdc>`__ +- `mongocxx::model::insert_one <{+api+}/classmongocxx_1_1v__noabi_1_1model_1_1insert__one.html>`__ +- `mongocxx::model::update_one <{+api+}/classmongocxx_1_1v__noabi_1_1model_1_1update__one.html>`__ +- `mongocxx::model::update_many <{+api+}/classmongocxx_1_1v__noabi_1_1model_1_1update__many.html>`__ +- `mongocxx::model::replace_one <{+api+}/classmongocxx_1_1v__noabi_1_1model_1_1replace__one.html>`__ +- `mongocxx::model::delete_one <{+api+}/classmongocxx_1_1v__noabi_1_1model_1_1delete__one.html>`__ +- `mongocxx::model::delete_many <{+api+}/classmongocxx_1_1v__noabi_1_1model_1_1delete__many.html>`__ +- `execute() <{+api+}/classmongocxx_1_1v__noabi_1_1bulk__write.html#a13476d87ed6d00dca52c39dc04b98568>`__ +- `mongocxx::options::bulk_write <{+api+}/classmongocxx_1_1v__noabi_1_1options_1_1bulk__write.html>`__ +- `mongocxx::result::bulk_write <{+api+}/classmongocxx_1_1v__noabi_1_1result_1_1bulk__write.html>`__ diff --git a/source/write/delete.txt b/source/write/delete.txt new file mode 100644 index 00000000..8063a5fa --- /dev/null +++ b/source/write/delete.txt @@ -0,0 +1,182 @@ +.. _cpp-write-delete: + +================ +Delete Documents +================ + +.. contents:: On this page + :local: + :backlinks: none + :depth: 2 + :class: singlecol + +.. facet:: + :name: genre + :values: reference + +.. meta:: + :keywords: remove, drop, code example + +Overview +-------- + +In this guide, you can learn how to use the {+driver-short+} to remove +documents from a MongoDB collection by performing **delete operations**. + +A delete operation removes one or more documents from a MongoDB collection. +You can perform a delete operation by using the ``delete_one()`` or +``delete_many()`` methods. + +Sample Data +~~~~~~~~~~~ + +The examples in this guide use the ``restaurants`` collection in the ``sample_restaurants`` +database from the :atlas:`Atlas sample datasets `. To access this collection +from your C++ application, instantiate a ``mongocxx::client`` that connects to an Atlas cluster +and assign the following values to your ``db`` and ``collection`` variables: + +.. literalinclude:: /includes/write/delete.cpp + :start-after: start-db-coll + :end-before: end-db-coll + :language: cpp + :dedent: + +To learn how to create a free MongoDB Atlas cluster and load the sample datasets, see the +:atlas:`Get Started with Atlas ` guide. + +Delete Operations +----------------- + +You can perform delete operations by using the following methods: + +- ``delete_one()``, which deletes *the first document* that matches the search criteria +- ``delete_many()``, which deletes *all documents* that match the search criteria + +Each delete method requires a **query filter** document, which specifies the +search criteria to determine which documents to select for removal. +For more information about query filters, see the +:manual:`Query Filter Documents section ` in +the {+mdb-server+} manual. + +Delete One Document +~~~~~~~~~~~~~~~~~~~ + +The following example uses the ``delete_one()`` method to remove a document in +the ``restaurants`` collection that has a ``name`` value of ``"Ready Penny Inn"``: + +.. literalinclude:: /includes/write/delete.cpp + :start-after: start-delete-one + :end-before: end-delete-one + :language: cpp + :dedent: + +Delete Multiple Documents +~~~~~~~~~~~~~~~~~~~~~~~~~ + +The following example uses the ``delete_many()`` method to remove all documents +in the ``restaurants`` collection that have a ``borough`` value of ``"Brooklyn"``: + +.. literalinclude:: /includes/write/delete.cpp + :start-after: start-delete-many + :end-before: end-delete-many + :language: cpp + :dedent: + +Customize the Delete Operation +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +You can modify the behavior of the ``delete_one()`` and ``delete_many()`` methods by +passing an instance of the ``mongocxx::options::delete_options`` class as an optional +parameter. The following table describes the fields you can set in a +``mongocxx::options::delete_options`` instance: + +.. list-table:: + :widths: 30 70 + :header-rows: 1 + + * - Field + - Description + + * - ``collation`` + - | Specifies the kind of language collation to use when sorting + results. For more information, see :manual:`Collation ` + in the {+mdb-server+} manual. + + * - ``write_concern`` + - | Sets the write concern for the operation. + For more information, see :manual:`Write Concern ` + in the {+mdb-server+} manual. + + * - ``hint`` + - | Gets or sets the index to scan for documents. + For more information, see the :manual:`hint statement ` + in the {+mdb-server+} manual. + + * - ``let`` + - | Specifies a document with a list of values to improve operation readability. + Values must be constant or closed expressions that don't reference document + fields. For more information, see the :manual:`let statement + ` in the + {+mdb-server+} manual. + + * - ``comment`` + - | Attaches a comment to the operation. For more information, see the :manual:`delete command + fields ` guide in the + {+mdb-server+} manual. + +The following example calls the ``delete_many()`` method to delete all documents in +the ``restaurants`` collection that have a ``name`` value containing the string ``"Mongo"``. +It also sets the ``comment`` field of a ``mongocxx::options::delete_options`` instance +to add a comment to the operation: + +.. literalinclude:: /includes/write/delete.cpp + :start-after: start-delete-options + :end-before: end-delete-options + :language: cpp + :dedent: + +.. tip:: + + If the preceding example used the ``delete_one()`` method instead of + ``delete_many()``, the driver would delete only the first document that has + a ``name`` value containing ``"Mongo"``. + +Return Value +~~~~~~~~~~~~ + +The ``delete_one()`` and ``delete_many()`` methods return an instance of +the ``mongocxx::result::delete_result`` class. This class contains the +following member functions: + +- ``result()``, which returns the raw bulk write result +- ``deleted_count()``, which returns the number of documents deleted + +If the query filter does not match any documents, the driver doesn't delete any +documents and ``deleted_count`` is 0. + +The following example calls the ``delete_many()`` method to delete documents +that have a ``cuisine`` value of ``"Greek"``. It then calls the ``deleted_count()`` +member function to print the number of deleted documents: + +.. io-code-block:: + + .. input:: /includes/write/delete.cpp + :start-after: start-delete-count + :end-before: end-delete-count + :language: cpp + :dedent: + + .. output:: + + Deleted documents: 111 + +API Documentation +~~~~~~~~~~~~~~~~~ + +To learn more about any of the methods or types discussed in this +guide, see the following API documentation: + +- `delete_one() <{+api+}/classmongocxx_1_1v__noabi_1_1collection.html#adecd9613670ec09aa02814d652ef0014>`__ +- `delete_many() <{+api+}/classmongocxx_1_1v__noabi_1_1collection.html#a8f8907150f76ab1ba31c52b23f0b50d7>`__ +- `mongocxx::options::delete_options <{+api+}/classmongocxx_1_1v__noabi_1_1options_1_1delete__options.html>`__ +- `mongocxx::result::delete_result <{+api+}/classmongocxx_1_1v__noabi_1_1result_1_1delete__result.html>`__ diff --git a/source/write/insert.txt b/source/write/insert.txt new file mode 100644 index 00000000..b258083f --- /dev/null +++ b/source/write/insert.txt @@ -0,0 +1,175 @@ +.. _cpp-write-insert: + +================ +Insert Documents +================ + +.. contents:: On this page + :local: + :backlinks: none + :depth: 2 + :class: singlecol + +.. facet:: + :name: genre + :values: reference + +.. meta:: + :keywords: code examples, write, save, create + +Overview +-------- + +In this guide, you can learn how to use the {+driver-short+} to add +documents to a MongoDB collection by performing **insert operations**. + +An insert operation inserts one or more documents into a MongoDB collection. +You can perform an insert operation by using the ``insert_one()`` method to +insert a single document or the ``insert_many()`` method to insert one or more +documents. + +Sample Data +~~~~~~~~~~~ + +The examples in this guide use the ``sample_restaurants.restaurants`` collection +from the :atlas:`Atlas sample datasets `. To access this collection +from your C++ application, instantiate a ``client`` that connects to an Atlas cluster +and assign the following values to your ``db`` and ``collection`` variables: + +.. literalinclude:: /includes/write/insert.cpp + :language: cpp + :dedent: + :start-after: start-db-coll + :end-before: end-db-coll + +To learn how to create a free MongoDB Atlas cluster and load the sample datasets, see +the :ref:`` tutorial. + +The ``_id`` Field +----------------- + +In a MongoDB collection, each document *must* contain an ``_id`` field +with a unique field value. + +MongoDB allows you to manage this field in two ways: + +- You can set this field for each document yourself, ensuring each + ``_id`` field value is unique. +- You can let the driver automatically generate unique ``ObjectId`` + values for each document ``_id``. + +Unless you can guarantee uniqueness, we recommend +letting the driver automatically generate ``_id`` values. + +.. note:: + + Duplicate ``_id`` values violate unique index constraints, which + causes the driver to return a ``mongocxx::bulk_write_exception`` + error. + +To learn more about the ``_id`` field, see the +:manual:`Unique Indexes ` guide in the {+mdb-server+} manual. + +To learn more about document structure and rules, see the +:manual:`Documents ` guide in the {+mdb-server+} manual. + +Insert One Document +------------------- + +To add a single document to a MongoDB collection, call the ``insert_one()`` +method and pass the document you want to add. + +The following example inserts a document into the ``restaurants`` collection: + +.. literalinclude:: /includes/write/insert.cpp + :language: cpp + :dedent: + :start-after: start-insert-one + :end-before: end-insert-one + +Insert Multiple Documents +------------------------- + +To add multiple documents to a MongoDB collection, call the ``insert_many()`` +method and pass a vector that stores the documents you want to add. + +The following example inserts two documents into the ``restaurants`` collection: + +.. literalinclude:: /includes/write/insert.cpp + :language: cpp + :dedent: + :start-after: start-insert-many + :end-before: end-insert-many + +Modify Insert Behavior +---------------------- + +You can modify the behavior of the ``insert_one()`` and ``insert_many()`` methods by +passing an instance of the ``mongocxx::options::insert`` class as an optional +parameter. The following table describes the fields you can set in a +``mongocxx::options::insert`` instance: + +.. list-table:: + :widths: 30 70 + :header-rows: 1 + + * - Field + - Description + + * - ``bypass_document_validation`` + - | If set to ``true``, allows the write to opt out of + :manual:`document-level validation `. + | Defaults to ``false``. + | **Type**: ``bool`` + + * - ``write_concern`` + - | Sets the write concern for the operation. + | Defaults to the write concern of the namespace. + | **Type**: ``mongocxx::write_concern`` + + * - ``ordered`` + - | If set to ``true``, the operation stops inserting documents when one insert + fails. If ``false``, the operation continues to insert the remaining documents + when one insert fails. + | Defaults to ``true``. + | **Type**: ``bool`` + + * - ``comment`` + - | A comment to attach to the operation. For more information, see the :manual:`insert command + fields ` guide in the + {+mdb-server+} manual. + | **Type**: ``bsoncxx::types::bson_value::view_or_value`` + +Example +~~~~~~~ + +The following code uses the ``insert_many()`` method to insert three new +documents into a collection. Because the ``bypass_document_validation`` field +is set to ``true`` in a ``mongocxx::options::insert`` instance, this +insert operation bypasses document-level validation: + +.. literalinclude:: /includes/write/insert.cpp + :language: cpp + :dedent: + :start-after: start-modify + :end-before: end-modify + +Additional Information +---------------------- + +.. TODO: + For runnable code examples of inserting documents with the {+driver-short+}, see + :ref:`cpp-write`. + +For more examples that use the ``insert_one()`` and ``insert_many()`` methods, see the +:ref:`cpp-tutorial-insert` section of the Tutorial page. + +API Documentation +~~~~~~~~~~~~~~~~~ + +To learn more about any of the methods or types discussed in this +guide, see the following API documentation: + +- `insert_one() <{+api+}/classmongocxx_1_1v__noabi_1_1collection.html#af040f1fcb1ac406037bf1cbcdb300061>`__ +- `insert_many() <{+api+}/classmongocxx_1_1v__noabi_1_1collection.html#a61ebaa0c63296761637ce45115512085>`__ +- `mongocxx::options::insert <{+api+}/classmongocxx_1_1v__noabi_1_1options_1_1insert.html>`__ \ No newline at end of file diff --git a/source/write/update.txt b/source/write/update.txt new file mode 100644 index 00000000..a5daa13d --- /dev/null +++ b/source/write/update.txt @@ -0,0 +1,227 @@ +.. _cpp-write-update: + +================ +Update Documents +================ + +.. contents:: On this page + :local: + :backlinks: none + :depth: 2 + :class: singlecol + +.. facet:: + :name: genre + :values: reference + +.. meta:: + :keywords: modify, change, bulk, code example + +Overview +-------- + +In this guide, you can learn how to use the {+driver-short+} to update +documents in a MongoDB collection. You can call the ``update_one()`` method +to update a single document or the ``update_many()`` method to update multiple +documents. + +Sample Data +~~~~~~~~~~~ + +The examples in this guide use the ``restaurants`` collection in the ``sample_restaurants`` +database from the :atlas:`Atlas sample datasets `. To access this collection +from your C++ application, instantiate a ``mongocxx::client`` that connects to an Atlas cluster +and assign the following values to your ``db`` and ``collection`` variables: + +.. literalinclude:: /includes/write/update.cpp + :start-after: start-db-coll + :end-before: end-db-coll + :language: cpp + :dedent: + +To learn how to create a free MongoDB Atlas cluster and load the sample datasets, see the +:atlas:`Get Started with Atlas ` guide. + +Update Operations +----------------- + +You can perform update operations in MongoDB by using the following methods: + +- ``update_one()``, which updates *the first document* that matches the search criteria +- ``update_many()``, which updates *all documents* that match the search criteria + +Each update method requires the following parameters: + +- **Query filter** document: Specifies which documents to update. For + more information about query filters, see the + :manual:`Query Filter Documents section ` in + the {+mdb-server+} manual. + +- **Update** document: Specifies the **update operator**, or the kind of update to + perform, and the fields and values to change. For a list of update operators + and their usage, see the :manual:`Field Update Operators guide + ` in the {+mdb-server+} manual. + +Update One Document +~~~~~~~~~~~~~~~~~~~ + +The following example uses the ``update_one()`` method to update the ``name`` +value of a document in the ``restaurants`` collection from ``"Bagels N Buns"`` +to ``"2 Bagels 2 Buns"``: + +.. literalinclude:: /includes/write/update.cpp + :start-after: start-update-one + :end-before: end-update-one + :language: cpp + :dedent: + +Update Many Documents +~~~~~~~~~~~~~~~~~~~~~ + +The following example uses the ``update_many()`` method to update all documents +that have a ``cuisine`` value of ``"Pizza"``. After the update, the documents have +a ``cuisine`` value of ``"Pasta"``. + +.. literalinclude:: /includes/write/update.cpp + :start-after: start-update-many + :end-before: end-update-many + :language: cpp + :dedent: + +Customize the Update Operation +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +You can modify the behavior of the ``update_one()`` and ``update_many()`` methods by +passing an instance of the ``mongocxx::options::update`` class as an optional +parameter. The following table describes the fields you can set in a +``mongocxx::options::update`` instance: + +.. list-table:: + :widths: 30 70 + :header-rows: 1 + + * - Field + - Description + + * - ``upsert`` + - | Specifies whether the update operation performs an upsert operation if no + documents match the query filter. For more information, see the :manual:`upsert + statement ` + in the {+mdb-server+} manual. + | Defaults to ``false``. + + * - ``bypass_document_validation`` + - | Specifies whether the update operation bypasses document validation. This lets you + update documents that don't meet the schema validation requirements, if any + exist. For more information about schema validation, see :manual:`Schema + Validation ` in the MongoDB + Server manual. + | Defaults to ``false``. + + * - ``collation`` + - | Specifies the kind of language collation to use when sorting + results. For more information, see :manual:`Collation ` + in the {+mdb-server+} manual. + + * - ``array_filters`` + - | Specifies which array elements an update applies to if the operation modifies + array fields. + + * - ``hint`` + - | Sets the index to scan for documents. + For more information, see the :manual:`hint statement ` + in the {+mdb-server+} manual. + + * - ``write_concern`` + - | Sets the write concern for the operation. + For more information, see :manual:`Write Concern ` + in the {+mdb-server+} manual. + + * - ``let`` + - | Specifies a document with a list of values to improve operation readability. + Values must be constant or closed expressions that don't reference document + fields. For more information, see the :manual:`let statement + ` in the + {+mdb-server+} manual. + + * - ``comment`` + - | A comment to attach to the operation. For more information, see the :manual:`insert command + fields ` guide in the + {+mdb-server+} manual for more information. + +The following example uses the ``update_many()`` method to find all documents that +have ``borough`` value of ``"Manhattan"``. It then updates the ``borough`` value +in these documents to ``"Manhattan (north)"``. Because the ``upsert`` option is +set to ``true``, the {+driver-short+} inserts a new document if the query filter doesn't +match any existing documents. + +.. literalinclude:: /includes/write/update.cpp + :start-after: start-update-options + :end-before: end-update-options + :language: cpp + :dedent: + +Return Value +~~~~~~~~~~~~ + +The ``update_one()`` and ``update_many()`` methods return an instance of +the ``mongocxx::result::update`` class. This class contains the following +member functions: + +.. list-table:: + :widths: 30 70 + :header-rows: 1 + + * - Function + - Description + + * - ``matched_count()`` + - | Returns the number of documents that matched the query filter, regardless of + how many were updated. + + * - ``modified_count()`` + - | Returns number of documents modified by the update operation. If an updated + document is identical to the original, it is not included in this + count. + + * - ``result()`` + - | Returns the raw result document for the operation. + + * - ``upserted_count()`` + - | Returns the number of document that were upserted into the database. + + * - ``upserted_id()`` + - | Returns the ID of the document that was upserted in the database, if the driver + performed an upsert. + +The following example uses the ``update_many()`` method to update the ``name`` field +of matching documents from ``"Dunkin' Donuts"`` to ``"Dunkin'"``. It calls the +``modified_count()`` member function to print the number of modified documents: + +.. io-code-block:: + + .. input:: /includes/write/update.cpp + :start-after: start-update-result + :end-before: end-update-result + :language: cpp + :dedent: + + .. output:: + + Modified documents: 206 + +Additional Information +---------------------- + +To learn more about creating query filters, see the :ref:`cpp-specify-query` guide. + +API Documentation +~~~~~~~~~~~~~~~~~ + +To learn more about any of the methods or types discussed in this +guide, see the following API documentation: + +- `update_one() <{+api+}/classmongocxx_1_1v__noabi_1_1collection.html#ab7dc140185de1492c52187b19e83d736>`__ +- `update_many() <{+api+}/classmongocxx_1_1v__noabi_1_1collection.html#afd3f0a4a09ad1338711b4c8f8c1beb93>`__ +- `mongocxx::options::update <{+api+}/classmongocxx_1_1v__noabi_1_1options_1_1update.html>`__ +- `mongocxx::result::update <{+api+}/classmongocxx_1_1v__noabi_1_1result_1_1update.html>`__ \ No newline at end of file