diff --git a/config/redirects b/config/redirects index 99597fd4..1fdf005d 100644 --- a/config/redirects +++ b/config/redirects @@ -17,3 +17,11 @@ raw: ${prefix}/master -> ${base}/upcoming/ [*-master]: ${prefix}/${version}/fundamentals/crud/write-operations/change-a-document/ -> ${base}/${version}/fundamentals/crud/write-operations/modify/ [*-master]: ${prefix}/${version}/fundamentals/connection/ -> ${base}/${version}/fundamentals/connections/connection-guide [*-master]: ${prefix}/${version}/fundamentals/network-compression/ -> ${base}/${version}/fundamentals/connections/network-compression/ +[*-master]: ${prefix}/${version}/fundamentals/crud/write-read-pref/ -> ${base}/${version}/crud/configure/ +[*-master]: ${prefix}/${version}/fundamentals/collations/ -> ${base}/${version}/crud/configure/ + +# CC Redirects +[v1.12-master]: ${prefix}/${version}/usage-examples/struct-tagging/ -> ${base}/${version}/data-formats/struct-tagging/ +[v1.12-master]: ${prefix}/${version}/fundamentals/context/ -> ${base}/${version}/context +[v1.12-master]: ${prefix}/${version}/usage-examples/changestream -> ${base}/${version}/monitoring-and-logging/change-streams/ +[v1.12-master]: ${prefix}/${version}/fundamentals/crud/read-operations/changestream/ -> ${base}/${version}/monitoring-and-logging/change-streams/ diff --git a/snooty.toml b/snooty.toml index 7e83afef..96383e35 100644 --- a/snooty.toml +++ b/snooty.toml @@ -1,9 +1,14 @@ name = "golang" title = "Go Driver" toc_landing_pages = [ - "/fundamentals/connections", - "/fundamentals/crud", - "/usage-examples", + "/connect", + "/context", + "/crud", + "/crud/update", + "/monitoring-and-logging", + "/security", + "/security/authentication", + "/connect/specify-connection-options", ] intersphinx = [ @@ -17,6 +22,7 @@ sharedinclude_root = "https://raw.githubusercontent.com/10gen/docs-shared/main/" api-version = "v2" driver-long = "MongoDB Go Driver" driver-short = "Go driver" +language = "Go" docs-branch = "master" version = "v2.1" full-version = "{+version+}.0" diff --git a/source/fundamentals/aggregation.txt b/source/aggregation.txt similarity index 98% rename from source/fundamentals/aggregation.txt rename to source/aggregation.txt index fccb3357..9e2cf456 100644 --- a/source/fundamentals/aggregation.txt +++ b/source/aggregation.txt @@ -25,6 +25,12 @@ pipeline consists of one or more **stages**. Each stage performs an operation based on its expression operators. After the driver executes the aggregation pipeline, it returns an aggregated result. +.. sharedinclude:: dbx/agg-tutorials-manual-tip.rst + + .. replacement:: language + + :guilabel:`{+language+}` + Analogy ~~~~~~~ diff --git a/source/archive-reference-files/faq.txt b/source/archive-reference-files/faq.txt new file mode 100644 index 00000000..c38a73e8 --- /dev/null +++ b/source/archive-reference-files/faq.txt @@ -0,0 +1,192 @@ +.. _golang-faq: + +=== +FAQ +=== + +.. facet:: + :name: genre + :values: reference + +.. meta:: + :keywords: code example, connection error, question, help + :description: Find answers to common questions about the MongoDB Go Driver, including connection pooling, error handling, and BSON to JSON conversion. + +.. contents:: On this page + :local: + :backlinks: none + :depth: 1 + :class: singlecol + +This page contains frequently asked questions and their corresponding answers. + +.. tip:: + + If you can't find an answer to your problem on this page, + see the :ref:`golang-issues-and-help` page for next steps and more + resources. + +Why Am I Getting Errors While Connecting to MongoDB? +---------------------------------------------------- + +If you have trouble connecting to a MongoDB deployment, see +the :ref:`Connection Troubleshooting Guide ` +for possible solutions. + +.. _golang-faq-connection-pool: + +How Does Connection Pooling Work in the {+driver-short+}? +--------------------------------------------------------- + +Every ``Client`` instance has a built-in connection pool for each server +in your MongoDB topology. Connection pools open sockets on demand to support +concurrent MongoDB operations, or `goroutines +`__, in your application. + +The maximum size of each connection pool is set by the ``maxPoolSize`` option, which +defaults to ``100``. If the number of in-use connections to a server reaches +the value of ``maxPoolSize``, the next request to that server will wait +until a connection becomes available. + +The ``Client`` instance opens two additional sockets per server in your +MongoDB topology for monitoring the server's state. + +For example, a client connected to a 3-node replica set opens 6 +monitoring sockets. It also opens the necessary sockets to support +an application's concurrent operations on each server, up to +the value of ``maxPoolSize``. If ``maxPoolSize`` is ``100`` and the +application only uses the primary (the default), then only the primary +connection pool grows and there can be at most ``106`` total connections. If the +application uses a :ref:`read preference ` to query the +secondary nodes, their pools also grow and there can be ``306`` total connections. + +Additionally, connection pools are rate-limited such that each connection pool +can only create, at maximum, the value of ``maxConnecting`` connections +in parallel at any time. Any additional goroutine stops waiting in the +following cases: + +- One of the existing goroutines finishes creating a connection, or + an existing connection is checked back into the pool. +- The driver's ability to reuse existing connections improves due to + rate-limits on connection creation. + +You can set the minimum number of concurrent connections to +each server by using the ``minPoolSize`` option, which defaults to ``0``. +After setting ``minPoolSize``, the connection pool is initialized with +this number of sockets. If sockets close due to any network errors, causing +the total number of sockets (both in use and idle) to drop below the minimum, more sockets +open until the minimum is reached. + +You can set the maximum number of milliseconds that a connection can +remain idle in the pool before being removed and replaced with +the ``maxIdleTimeMS`` option, which defaults to ``None`` (no limit). + +The following default configuration for a ``Client`` works for most applications: + +.. code-block:: go + + client, err := mongo.Connect(options.Client().ApplyURI("")) + +Create a client once for each process, and reuse it for all +operations. It is a common mistake to create a new client for each +request, which is very inefficient. + +To support high numbers of concurrent MongoDB operations +within one process, you can increase ``maxPoolSize``. Once the pool +reaches its maximum size, additional operations wait for sockets +to become available. + +The driver does not limit the number of operations that +can wait for sockets to become available and it is the application's +responsibility to limit the size of its pool to bound queuing +during a load spike. Operations can wait for any length of time +unless you define the ``waitQueueTimeoutMS`` option. + +An operation that waits more than the length of time defined by +``waitQueueTimeoutMS`` for a socket raises a connection error. Use this +option if it is more important to bound the duration of operations +during a load spike than it is to complete every operation. + +When ``Client.Disconnect()`` is called by any goroutine, the driver +closes all idle sockets and closes all sockets that are in +use as they are returned to the pool. + +How Can I Fix the "WriteNull can only write while positioned on a Element or Value but is positioned on a TopLevel" Error? +-------------------------------------------------------------------------------------------------------------------------- + +The ``bson.Marshal()`` method requires a parameter that can be decoded +into a BSON document, such as the ``bson.D`` type. This error occurs +when you pass something *other* than a BSON document to +``bson.Marshal()``. + +The ``WriteNull`` error occurs when you pass a ``null`` to +``bson.Marshal()``. Situations in which a similar error can occur +include the following: + +- You pass a string to ``bson.Marshal()``, causing a ``WriteString`` error. +- You pass a boolean to ``bson.Marshal()``, causing a ``WriteBoolean`` error. +- You pass an integer to ``bson.Marshal()``, causing a ``WriteInt32`` error. + +You may encounter this error when you perform a CRUD operation that +internally uses the ``bson.Marshal()`` method or when you call +``bson.Marshal()`` directly to encode data. + +The following code produces a ``WriteNull`` error because the driver +cannot encode the ``null`` value of ``sortOrder`` to BSON during +the ``FindOneAndUpdate()`` operation: + +.. code-block:: go + + var sortOrder bson.D + opts := options.FindOneAndUpdate().SetSort(sortOrder) + + updateDocument := bson.D{{"$inc", bson.D{{"counter", 1}}}} + result := coll.FindOneAndUpdate(context.TODO(), bson.D{}, updateDocument, opts) + if err := result.Err(); err != nil { + panic(err) + } + +The following code shows how to correctly initialize the ``sortOrder`` +variable as a ``bson.D`` type so that the driver can convert it to BSON: + +.. code-block:: go + + sortOrder := bson.D{} + +How Do I Convert a BSON Document to JSON? +----------------------------------------- + +The driver provides a variety of marshaler methods that can be used to +convert a BSON document to JSON, such as the ``MarshalExtJSON()`` +method. To view a readable form of the JSON encoding, you must use +an unmarshaler method or string type-casting to parse the JSON byte +format. + +The following code converts a BSON document to JSON using the +``MarshalExtJSON()`` method, then parses and prints the JSON byte array +using string type-casting: + +.. io-code-block:: + :copyable: true + + .. input:: + :language: go + :emphasize-lines: 3 + + bsonDocument := bson.D{{"hello", "world"}} + + jsonBytes, err := bson.MarshalExtJSON(bsonDocument, true, false) + if err != nil { + panic(err) + } + + fmt.Println(string(jsonBytes)) + + .. output:: + :language: none + :visible: false + + {"hello":"world"} + +To learn more about conversions between BSON and Go types, see the +:ref:`golang-bson` guide. diff --git a/source/fundamentals.txt b/source/archive-reference-files/fundamentals.txt similarity index 100% rename from source/fundamentals.txt rename to source/archive-reference-files/fundamentals.txt diff --git a/source/fundamentals/auth.txt b/source/archive-reference-files/fundamentals/auth.txt similarity index 100% rename from source/fundamentals/auth.txt rename to source/archive-reference-files/fundamentals/auth.txt diff --git a/source/fundamentals/collations.txt b/source/archive-reference-files/fundamentals/collations.txt similarity index 100% rename from source/fundamentals/collations.txt rename to source/archive-reference-files/fundamentals/collations.txt diff --git a/source/fundamentals/context.txt b/source/archive-reference-files/fundamentals/context.txt similarity index 99% rename from source/fundamentals/context.txt rename to source/archive-reference-files/fundamentals/context.txt index b2487b0d..16f388ea 100644 --- a/source/fundamentals/context.txt +++ b/source/archive-reference-files/fundamentals/context.txt @@ -1,4 +1,3 @@ -.. _golang-context: ======= Context diff --git a/source/fundamentals/crud/read-operations.txt b/source/archive-reference-files/fundamentals/crud/read-operations.txt similarity index 100% rename from source/fundamentals/crud/read-operations.txt rename to source/archive-reference-files/fundamentals/crud/read-operations.txt diff --git a/source/fundamentals/crud/read-operations/changestream.txt b/source/archive-reference-files/fundamentals/crud/read-operations/changestream.txt similarity index 99% rename from source/fundamentals/crud/read-operations/changestream.txt rename to source/archive-reference-files/fundamentals/crud/read-operations/changestream.txt index 13c8d553..b4315de3 100644 --- a/source/fundamentals/crud/read-operations/changestream.txt +++ b/source/archive-reference-files/fundamentals/crud/read-operations/changestream.txt @@ -1,6 +1,3 @@ -.. _golang-watch-changes: -.. _golang-monitor-changes: - ==================== Monitor Data Changes ==================== diff --git a/source/archive-reference-files/fundamentals/crud/read-operations/count.txt b/source/archive-reference-files/fundamentals/crud/read-operations/count.txt new file mode 100644 index 00000000..89fce652 --- /dev/null +++ b/source/archive-reference-files/fundamentals/crud/read-operations/count.txt @@ -0,0 +1,259 @@ +=============== +Count Documents +=============== + +.. meta:: + :description: Learn to count documents in a MongoDB collection using Go, including accurate, estimated, and aggregation-based methods. + +.. contents:: On this page + :local: + :backlinks: none + :depth: 1 + :class: singlecol + +Overview +-------- + +In this guide, you can learn how to get an :ref:`accurate +` and :ref:`estimated ` count of +the number of documents in your collection. + +Sample Data +~~~~~~~~~~~ + +The examples in this section use the following ``Tea`` struct as a model for documents +in the ``tea`` collection: + +.. literalinclude:: /includes/fundamentals/code-snippets/CRUD/countAndEstimate.go + :start-after: start-tea-struct + :end-before: end-tea-struct + :language: go + :dedent: + +To run the examples in this guide, load the sample data into the ``tea`` collection in the ``db`` +database with the following snippet: + +.. literalinclude:: /includes/fundamentals/code-snippets/CRUD/countAndEstimate.go + :language: go + :dedent: + :start-after: begin insert docs + :end-before: end insert docs + +.. include:: /includes/fundamentals/automatic-db-coll-creation.rst + +Each document describes a tea type and its rating. These items +correspond to the ``type`` and ``rating`` fields. + +.. _golang-accurate-count: + +Accurate Count +-------------- + +To count the number of documents that match your query filter, use the +``CountDocuments()`` method. If you pass an empty query filter, this method +returns the total number of documents in the collection. + +.. tip:: + + When you use ``CountDocuments()`` to return the total number of documents in a + collection, MongoDB performs a collection scan. You can avoid a collection scan and + improve the performance of this method by using a :manual:`hint + ` to take advantage of the built-in index on + the ``_id`` field. Use this technique only when calling ``CountDocuments()`` + with an empty query parameter. + + .. code-block:: go + :emphasize-lines: 1, 3 + + opts := options.Count().SetHint("_id_") + + count, err := coll.CountDocuments(context.TODO(), bson.D{}, opts) + if err != nil { + panic(err) + } + +Modify Behavior +~~~~~~~~~~~~~~~ + +You can modify the behavior of ``CountDocuments()`` by passing in a +``CountOptions`` type. If you don't specify any options, the driver uses +its default values. + +The ``CountOptions`` type allows you to configure options with the +following methods: + +.. list-table:: + :widths: 30 70 + :header-rows: 1 + + * - Method + - Description + + * - ``SetCollation()`` + - | The type of language collation to use when sorting results. + | Default: ``nil`` + + * - ``SetHint()`` + - | The index to use to scan for documents to count. + | Default: ``nil`` + + * - ``SetLimit()`` + - | The maximum number of documents to count. + | Default: ``0`` + + * - ``SetSkip()`` + - | The number of documents to skip before counting. + | Default: ``0`` + +Example +``````` + +The following example counts the number of documents where the +``rating`` is less than ``6``: + +.. io-code-block:: + :copyable: true + + .. input:: + :language: go + + filter := bson.D{{"rating", bson.D{{"$lt", 6}}}} + + count, err := coll.CountDocuments(context.TODO(), filter) + if err != nil { + panic(err) + } + fmt.Printf("Number of documents with a rating less than six: %d\n", count) + + .. output:: + :language: none + :visible: false + + Number of documents with a rating less than six: 4 + +.. _golang-count-aggregation: + +Aggregation +----------- + +You can also include the :manual:`$count ` +stage to count the number of documents in an aggregation pipeline. + +Example +~~~~~~~ + +The following example performs the following actions: + +- Counts the number of documents in which the value of the ``rating`` field is greater + than ``5`` +- Assigns the count to the ``counted_documents`` field + +.. io-code-block:: + :copyable: true + + .. input:: + :language: go + + matchStage := bson.D{{"$match", bson.D{{"rating", bson.D{{"$gt", 5}}}}}} + countStage := bson.D{{"$count", "counted_documents"}} + + cursor, err := coll.Aggregate(context.TODO(), mongo.Pipeline{matchStage, countStage}) + if err != nil { + panic(err) + } + + var results []bson.D + if err = cursor.All(context.TODO(), &results); err != nil { + panic(err) + } + for _, result := range results { + fmt.Println(result) + } + + .. output:: + :language: none + :visible: false + + [{counted_documents 5}] + +.. _golang-estimated-count: + +Estimated Count +--------------- + +To estimate the number of documents in your collection, use the +``EstimatedDocumentCount()`` method. + +.. note:: + + The ``EstimatedDocumentCount()`` method is quicker than the + ``CountDocuments()`` method because it uses the collection's + metadata rather than scanning the entire collection. + +Modify Behavior +~~~~~~~~~~~~~~~ + +You can modify the behavior of ``EstimatedDocumentCount()`` by passing +in an ``EstimatedDocumentCountOptions`` type. If you don't specify any +options, the driver uses its default values. + +The ``EstimatedDocumentCountOptions`` type allows you to configure +options by using the following methods: + +.. list-table:: + :widths: 30 70 + :header-rows: 1 + + * - Method + - Description + + * - ``SetComment()`` + - | Sets a comment to attach to the count operation. + | Default: ``nil`` + +Example +``````` + +The following example estimates the number of documents in the +``tea`` collection: + +.. io-code-block:: + :copyable: true + + .. input:: + :language: go + + count, err := coll.EstimatedDocumentCount(context.TODO()) + if err != nil { + panic(err) + } + fmt.Printf("Estimated number of documents in the tea collection: %d\n", count) + + .. output:: + :language: none + :visible: false + + Estimated number of documents in the tea collection: 9 + +Additional Information +---------------------- + +To learn more about the operations mentioned, see the following +guides: + +- :ref:`golang-query-document` +- :ref:`golang-skip` +- :ref:`golang-limit` +- :ref:`golang-aggregation` +- :ref:`golang-collations` + +API Documentation +~~~~~~~~~~~~~~~~~ + +To learn more about any of the methods or types discussed in this +guide, see the following API Documentation: + +- `CountDocuments() <{+api+}/mongo#Collection.CountDocuments>`__ +- `CountOptions <{+api+}/mongo/options#CountOptions>`__ +- `EstimatedDocumentCount() <{+api+}/mongo#Collection.EstimatedDocumentCount>`__ +- `EstimatedDocumentCountOptions <{+api+}/mongo/options#EstimatedDocumentCountOptions>`__ diff --git a/source/fundamentals/crud/read-operations/limit.txt b/source/archive-reference-files/fundamentals/crud/read-operations/limit.txt similarity index 99% rename from source/fundamentals/crud/read-operations/limit.txt rename to source/archive-reference-files/fundamentals/crud/read-operations/limit.txt index 226c97fd..83803351 100644 --- a/source/fundamentals/crud/read-operations/limit.txt +++ b/source/archive-reference-files/fundamentals/crud/read-operations/limit.txt @@ -1,5 +1,3 @@ -.. _golang-limit: - ==================================== Limit the Number of Returned Results ==================================== diff --git a/source/fundamentals/crud/read-operations/skip.txt b/source/archive-reference-files/fundamentals/crud/read-operations/skip.txt similarity index 99% rename from source/fundamentals/crud/read-operations/skip.txt rename to source/archive-reference-files/fundamentals/crud/read-operations/skip.txt index 9458460f..d7ad895b 100644 --- a/source/fundamentals/crud/read-operations/skip.txt +++ b/source/archive-reference-files/fundamentals/crud/read-operations/skip.txt @@ -1,5 +1,3 @@ -.. _golang-skip: - ===================== Skip Returned Results ===================== diff --git a/source/fundamentals/crud/read-operations/sort.txt b/source/archive-reference-files/fundamentals/crud/read-operations/sort.txt similarity index 98% rename from source/fundamentals/crud/read-operations/sort.txt rename to source/archive-reference-files/fundamentals/crud/read-operations/sort.txt index a3fba2c5..4b44a237 100644 --- a/source/fundamentals/crud/read-operations/sort.txt +++ b/source/archive-reference-files/fundamentals/crud/read-operations/sort.txt @@ -1,5 +1,3 @@ -.. _golang-sort-results: - ============ Sort Results ============ @@ -286,4 +284,4 @@ guide, see the following API Documentation: - `FindOneAndDelete() <{+api+}/mongo#Collection.FindOneAndDelete>`__ - `FindOneAndUpdate() <{+api+}/mongo#Collection.FindOneAndUpdate>`__ - `FindOneAndReplace() <{+api+}/mongo#Collection.FindOneAndReplace>`__ -- `GridFSBucket.Find() <{+api+}/mongo#GridFSBucket.Find>`__ \ No newline at end of file +- `GridFSBucket.Find() <{+api+}/mongo#GridFSBucket.Find>`__ diff --git a/source/fundamentals/crud/write-operations.txt b/source/archive-reference-files/fundamentals/crud/write-operations.txt similarity index 100% rename from source/fundamentals/crud/write-operations.txt rename to source/archive-reference-files/fundamentals/crud/write-operations.txt diff --git a/source/fundamentals/crud/write-read-pref.txt b/source/archive-reference-files/fundamentals/crud/write-read-pref.txt similarity index 99% rename from source/fundamentals/crud/write-read-pref.txt rename to source/archive-reference-files/fundamentals/crud/write-read-pref.txt index 62847b1c..3f3f2bf7 100644 --- a/source/fundamentals/crud/write-read-pref.txt +++ b/source/archive-reference-files/fundamentals/crud/write-read-pref.txt @@ -1,5 +1,3 @@ -.. _golang-write-read-pref: - =================================== Modify Execution of CRUD Operations =================================== @@ -39,8 +37,6 @@ the following levels: In the following sections, you can learn how to customize the consistency and availability of the data in your replica sets. -.. _golang-writeconcern: - Write Concern ------------- diff --git a/source/fundamentals/enterprise-auth.txt b/source/archive-reference-files/fundamentals/enterprise-auth.txt similarity index 99% rename from source/fundamentals/enterprise-auth.txt rename to source/archive-reference-files/fundamentals/enterprise-auth.txt index cd539b55..68529c1a 100644 --- a/source/fundamentals/enterprise-auth.txt +++ b/source/archive-reference-files/fundamentals/enterprise-auth.txt @@ -198,8 +198,6 @@ address of your MongoDB server: authenticates using the PLAIN Simple Authentication and Security Layer (SASL) defined in `RFC-4616 `__. -.. _golang-mongodb-oidc: - MONGODB-OIDC ------------ @@ -479,8 +477,6 @@ callback function that you defined: :end-before: end-credential-callback :emphasize-lines: 6 -.. _golang-kubernetes-oidc: - Kubernetes ~~~~~~~~~~ diff --git a/source/fundamentals/monitoring.txt b/source/archive-reference-files/fundamentals/monitoring.txt similarity index 96% rename from source/fundamentals/monitoring.txt rename to source/archive-reference-files/fundamentals/monitoring.txt index 0b47891d..c67c5e3c 100644 --- a/source/fundamentals/monitoring.txt +++ b/source/archive-reference-files/fundamentals/monitoring.txt @@ -1,4 +1,3 @@ -.. _golang-monitoring: ========== Monitoring diff --git a/source/fundamentals/monitoring/cluster-monitoring.txt b/source/archive-reference-files/fundamentals/monitoring/cluster-monitoring.txt similarity index 100% rename from source/fundamentals/monitoring/cluster-monitoring.txt rename to source/archive-reference-files/fundamentals/monitoring/cluster-monitoring.txt diff --git a/source/fundamentals/monitoring/command-monitoring.txt b/source/archive-reference-files/fundamentals/monitoring/command-monitoring.txt similarity index 100% rename from source/fundamentals/monitoring/command-monitoring.txt rename to source/archive-reference-files/fundamentals/monitoring/command-monitoring.txt diff --git a/source/fundamentals/monitoring/connection-monitoring.txt b/source/archive-reference-files/fundamentals/monitoring/connection-monitoring.txt similarity index 100% rename from source/fundamentals/monitoring/connection-monitoring.txt rename to source/archive-reference-files/fundamentals/monitoring/connection-monitoring.txt diff --git a/source/fundamentals/time-series.txt b/source/archive-reference-files/fundamentals/time-series.txt similarity index 100% rename from source/fundamentals/time-series.txt rename to source/archive-reference-files/fundamentals/time-series.txt diff --git a/source/archive-reference-files/issues-and-help.txt b/source/archive-reference-files/issues-and-help.txt new file mode 100644 index 00000000..39902616 --- /dev/null +++ b/source/archive-reference-files/issues-and-help.txt @@ -0,0 +1,56 @@ +.. _golang-issues-and-help: + +============= +Issues & Help +============= + +.. facet:: + :name: genre + :values: reference + +.. meta:: + :keywords: suggestion, github + :description: Find support for the MongoDB Go Driver through community forums, report bugs or feature requests via JIRA, and create pull requests to contribute. + +We are lucky to have a vibrant MongoDB Go community that includes users +with varying levels of experience using the Go driver. We find the quickest +way to get support for general questions is through the `MongoDB Community Forums `_. + +To learn more, refer to our `support channels `_. + +Bugs / Feature Requests +----------------------- + +If you think you've found a bug or want to see a new feature in the Go +driver, please open a case in our issue management tool, JIRA: + +* `Create an account and log in `_. +* Navigate to `the GODRIVER project `_. +* Click **Create Issue**. Please provide as much information as possible + about the issue and the steps to reproduce it. + +Bug reports in JIRA for the Go driver and the Core Server (i.e. SERVER) project are **public**. + +If you've identified a security vulnerability in a driver or any other +MongoDB project, please report it according to the instructions found in the +:manual:`Create a Vulnerability Report page `. + +Pull Requests +------------- + +We are happy to accept contributions to help improve the driver. We will guide +user contributions to ensure they meet the standards of the codebase. Please +ensure that any pull requests include documentation, tests, and pass the +**gradle** checks. + +To get started, check out the source and work on a branch: + +.. code-block:: bash + + $ git clone https://github.com/mongodb/mongo-go-driver.git + $ cd mongo-go-driver + $ git checkout -b myNewFeature + +Finally, follow the `Testing/Development guidelines +`__ to +ensure your code passes any newly added and existing tests. diff --git a/source/archive-reference-files/quick-start.txt b/source/archive-reference-files/quick-start.txt new file mode 100644 index 00000000..c09e609b --- /dev/null +++ b/source/archive-reference-files/quick-start.txt @@ -0,0 +1,117 @@ +.. _golang-quickstart: + +===================== +Go Driver Quick Start +===================== + +.. contents:: On this page + :local: + :backlinks: none + :depth: 2 + :class: singlecol + +.. facet:: + :name: genre + :values: tutorial + +.. meta:: + :keywords: tutorial, get started, code example + :description: Learn to connect a Go application to a MongoDB Atlas cluster using the MongoDB Go Driver, including setting up a project, creating a cluster, and running queries. + +.. include:: /includes/quick-start/overview.rst + +Set Up Your Project +------------------- + +.. procedure:: + :style: connected + + .. step:: Create and initialize your project + + Create a new directory and initialize your project by using ``go mod``, as + shown in the following commands: + + .. code-block:: shell + + mkdir go-quickstart + cd go-quickstart + go mod init go-quickstart + + .. step:: Add the {+driver-long+} as a dependency + + Use ``go get`` to add the {+driver-short+} as a dependency, as shown in + the following command: + + .. code-block:: shell + + go get go.mongodb.org/mongo-driver/v2/mongo + +Create a MongoDB Cluster +------------------------ + +.. include:: /includes/quick-start/atlas-setup.rst + +Query Your MongoDB Cluster from Your Application +------------------------------------------------ + +.. procedure:: + :style: connected + + .. step:: Add your connection string + + In your terminal, run the following command to create an environment + variable called ``MONGODB_URI`` and set your Atlas connection string as + its value: + + .. code-block:: bash + + export MONGODB_URI='' + + .. note:: + + Make sure to replace the ```` section of the connection + string with the password you created for your user that has + **atlasAdmin** permissions. + + .. step:: Create a new file + + Run the following command from the base directory of your project to + create a new file called ``main.go``: + + .. code-block:: shell + + touch main.go + + .. step:: Create your Go application + + Copy and paste the following code into your ``main.go`` file. This code + runs a query on your sample dataset in MongoDB Atlas. + + .. literalinclude:: /includes/quick-start/main.go + :language: go + :dedent: + + .. step:: Run your application + + Run the sample code with the following command from your command line: + + .. code-block:: bash + + go run main.go + + .. include:: /includes/quick-start/query-output.rst + + .. tip:: + + If you receive no output or an error, check whether you properly set up + your environment variable and ensure you have loaded the + :atlas:`sample datasets ` into your cluster. + +After you complete these steps, you have a working application that uses +the {+driver-long+} to connect to your MongoDB cluster, runs a query on the +sample data, and prints out the result. + +Next Steps +---------- + +.. include:: /includes/quick-start/next-steps.rst diff --git a/source/archive-reference-files/usage-examples.txt b/source/archive-reference-files/usage-examples.txt new file mode 100644 index 00000000..a1a82df0 --- /dev/null +++ b/source/archive-reference-files/usage-examples.txt @@ -0,0 +1,113 @@ +.. _golang-usage-examples: + +============== +Usage Examples +============== + +.. contents:: On this page + :local: + :backlinks: none + :depth: 1 + :class: singlecol + +.. facet:: + :name: genre + :values: reference + +.. meta:: + :keywords: read, write, example, code example + :description: Explore Go usage examples for common MongoDB operations, including finding, inserting, updating, and deleting documents, as well as monitoring data changes. + +.. toctree:: + + Find Operations + Write Operations + Bulk Operations + Open a Change Stream + Count Documents Method + Distinct Field Values + Run a Command + Use Struct Tags + +Overview +-------- + +Usage examples provide convenient starting points for popular MongoDB +operations. Each example provides the following: + +- A full Go program that you can run in your own environment +- The expected result after running the program + +How to Use the Usage Examples +----------------------------- + +These examples use the :atlas:`sample datasets ` provided by +Atlas. You can load them into your database on the free tier of MongoDB +Atlas by following the :atlas:`Get Started with Atlas Guide +` or you can +:guides:`import the sample dataset into a local MongoDB instance +`. + +Once you import the dataset, you can copy and paste a usage +example into your development environment of choice. You can follow the +:ref:`Quick Start ` to learn more about getting +started with the {+driver-long+}. + +Connection String +~~~~~~~~~~~~~~~~~ + +Follow the :ref:`"Connect to your Cluster" ` +step to find the +:manual:`connection string ` to define your +``MONGODB_URI`` environment variable to run the usage examples. If your +instance uses :manual:`SCRAM authentication `, +you can replace ```` with your database username, ```` with your +database password, and ```` with the URL or IP address of your instance. + +To learn more about connecting to your MongoDB instance, see :ref:`golang-connection-guide`. + +Environment Variable +~~~~~~~~~~~~~~~~~~~~ + +To connect the example to your MongoDB instance, you must :ref:`define +an environment variable ` by using +your connection string. + +.. code-block:: go + + uri := os.Getenv("MONGODB_URI") + +.. _golang-usage-examples-env-variable: + +You can use `GoDotEnv `__ to define +your environment variable. + +Add the following application configuration in your ``.env`` file at the +root of your project, replacing the placeholders with the values for your +deployment's connection string. To learn more, see the +`GoDotEnv documentation `__. + +.. code-block:: + + MONGODB_URI=mongodb+srv://:@?retryWrites=true&w=majority + +Examples +-------- + +You can find usage examples for the following tasks: + +- :ref:`golang-find-one` +- :ref:`golang-find-multiple` +- :ref:`golang-insert-one` +- :ref:`golang-insert-many` +- :ref:`golang-update-one` +- :ref:`golang-update-many` +- :ref:`golang-replace` +- :ref:`golang-delete-one` +- :ref:`golang-delete-many` +- :ref:`golang-bulk-ops-usage-example` +- :ref:`golang-watch` +- :ref:`golang-count-usage-example` +- :ref:`golang-distinct-usage-example` +- :ref:`golang-run-command-usage-example` +- :ref:`golang-struct-tags-usage-example` diff --git a/source/usage-examples/bulkWrite.txt b/source/archive-reference-files/usage-examples/bulkWrite.txt similarity index 100% rename from source/usage-examples/bulkWrite.txt rename to source/archive-reference-files/usage-examples/bulkWrite.txt diff --git a/source/usage-examples/changestream.txt b/source/archive-reference-files/usage-examples/changestream.txt similarity index 100% rename from source/usage-examples/changestream.txt rename to source/archive-reference-files/usage-examples/changestream.txt diff --git a/source/usage-examples/command.txt b/source/archive-reference-files/usage-examples/command.txt similarity index 100% rename from source/usage-examples/command.txt rename to source/archive-reference-files/usage-examples/command.txt diff --git a/source/usage-examples/count.txt b/source/archive-reference-files/usage-examples/count.txt similarity index 100% rename from source/usage-examples/count.txt rename to source/archive-reference-files/usage-examples/count.txt diff --git a/source/usage-examples/deleteMany.txt b/source/archive-reference-files/usage-examples/deleteMany.txt similarity index 100% rename from source/usage-examples/deleteMany.txt rename to source/archive-reference-files/usage-examples/deleteMany.txt diff --git a/source/usage-examples/deleteOne.txt b/source/archive-reference-files/usage-examples/deleteOne.txt similarity index 100% rename from source/usage-examples/deleteOne.txt rename to source/archive-reference-files/usage-examples/deleteOne.txt diff --git a/source/usage-examples/distinct.txt b/source/archive-reference-files/usage-examples/distinct.txt similarity index 100% rename from source/usage-examples/distinct.txt rename to source/archive-reference-files/usage-examples/distinct.txt diff --git a/source/usage-examples/facets.toml b/source/archive-reference-files/usage-examples/facets.toml similarity index 100% rename from source/usage-examples/facets.toml rename to source/archive-reference-files/usage-examples/facets.toml diff --git a/source/usage-examples/find-operations.txt b/source/archive-reference-files/usage-examples/find-operations.txt similarity index 100% rename from source/usage-examples/find-operations.txt rename to source/archive-reference-files/usage-examples/find-operations.txt diff --git a/source/usage-examples/find.txt b/source/archive-reference-files/usage-examples/find.txt similarity index 100% rename from source/usage-examples/find.txt rename to source/archive-reference-files/usage-examples/find.txt diff --git a/source/usage-examples/findOne.txt b/source/archive-reference-files/usage-examples/findOne.txt similarity index 98% rename from source/usage-examples/findOne.txt rename to source/archive-reference-files/usage-examples/findOne.txt index 4d0e9737..b7b86617 100644 --- a/source/usage-examples/findOne.txt +++ b/source/archive-reference-files/usage-examples/findOne.txt @@ -1,4 +1,3 @@ -.. _golang-find-one: =============== Find a Document diff --git a/source/usage-examples/insertMany.txt b/source/archive-reference-files/usage-examples/insertMany.txt similarity index 100% rename from source/usage-examples/insertMany.txt rename to source/archive-reference-files/usage-examples/insertMany.txt diff --git a/source/usage-examples/insertOne.txt b/source/archive-reference-files/usage-examples/insertOne.txt similarity index 100% rename from source/usage-examples/insertOne.txt rename to source/archive-reference-files/usage-examples/insertOne.txt diff --git a/source/usage-examples/replaceOne.txt b/source/archive-reference-files/usage-examples/replaceOne.txt similarity index 100% rename from source/usage-examples/replaceOne.txt rename to source/archive-reference-files/usage-examples/replaceOne.txt diff --git a/source/usage-examples/struct-tagging.txt b/source/archive-reference-files/usage-examples/struct-tagging.txt similarity index 98% rename from source/usage-examples/struct-tagging.txt rename to source/archive-reference-files/usage-examples/struct-tagging.txt index 40a82b24..8e6aca07 100644 --- a/source/usage-examples/struct-tagging.txt +++ b/source/archive-reference-files/usage-examples/struct-tagging.txt @@ -1,4 +1,3 @@ -.. _golang-struct-tags-usage-example: =============== Use Struct Tags diff --git a/source/usage-examples/updateMany.txt b/source/archive-reference-files/usage-examples/updateMany.txt similarity index 100% rename from source/usage-examples/updateMany.txt rename to source/archive-reference-files/usage-examples/updateMany.txt diff --git a/source/usage-examples/updateOne.txt b/source/archive-reference-files/usage-examples/updateOne.txt similarity index 100% rename from source/usage-examples/updateOne.txt rename to source/archive-reference-files/usage-examples/updateOne.txt diff --git a/source/usage-examples/write-operations.txt b/source/archive-reference-files/usage-examples/write-operations.txt similarity index 100% rename from source/usage-examples/write-operations.txt rename to source/archive-reference-files/usage-examples/write-operations.txt diff --git a/source/atlas-search.txt b/source/atlas-search.txt new file mode 100644 index 00000000..44bb790a --- /dev/null +++ b/source/atlas-search.txt @@ -0,0 +1,111 @@ +.. _golang-atlas-search: + +========================= +Run an Atlas Search Query +========================= + +.. facet:: + :name: genre + :values: reference + +.. meta:: + :keywords: full text, text analyzer, meta, pipeline, scoring, Lucene + :description: Learn about how to use Atlas Search in the {+driver-long+}. + +.. contents:: On this page + :local: + :backlinks: none + :depth: 2 + :class: singlecol + +Overview +-------- + +In this guide, you can learn how to use the {+driver-short+} to +run :atlas:`Atlas Search ` queries on a collection. +Atlas Search enables you to perform full-text searches on collections +hosted on MongoDB Atlas. Atlas Search indexes specify the behavior of the +search and which fields to index. + +Sample Data +~~~~~~~~~~~ + +The example in this guide uses the ``movies`` collection in the ``sample_mflix`` +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. + +Run an Atlas Search Query +------------------------- + +This section shows how to create an aggregation pipeline to run an +Atlas Search query on a collection. + +To run an Atlas Search query, you must create an Atlas Search index on your +collection. To learn how to programmatically create +an Atlas Search index, see the :ref:`golang-atlas-search-indexes` section of the +Indexes guide. + +After you create an Atlas Search index, add the ``$search`` stage in your array +of pipeline stages to specify the search criteria. Then, call +the ``Aggregate()`` method and pass your pipeline array as a parameter. + +.. tip:: + + To learn more about aggregation operations, see the :ref:`golang-aggregation` + guide. + +Atlas Search Example +~~~~~~~~~~~~~~~~~~~~ + +This example runs an Atlas Search query by performing the +following actions: + +- Creates a ``$search`` stage that instructs the driver + to query for documents in which the ``title`` field contains + the word ``"Alabama"`` + +- Creates a ``$project`` stage that instructs the driver to + include the ``title`` field in the query results + +- Passes the pipeline stages to the ``Aggregate()`` method and + prints the results + +.. io-code-block:: + :copyable: + + .. input:: /includes/fundamentals/code-snippets/indexes/atlasSearch.go + :start-after: begin-atlas-search + :end-before: end-atlas-search + :language: go + :dedent: + + .. output:: + :language: console + :visible: false + + { + _id: new ObjectId('...'), + title: 'Alabama Moon' + } + { + _id: new ObjectId('...'), + title: 'Crazy in Alabama' + } + { + _id: new ObjectId('...'), + title: 'Sweet Home Alabama' + } + +Additional Information +---------------------- + +To learn more about Atlas Search, see the :atlas:`Atlas Search ` +guides and the :atlas:`$search ` pipeline +stage reference in the Atlas documentation. + +API Documentation +~~~~~~~~~~~~~~~~~ + +To learn more about the ``Aggregate()`` method, see the +`API documentation <{+api+}/mongo#Collection.Aggregate>`__. diff --git a/source/fundamentals/atlas-vector-search.txt b/source/atlas-vector-search.txt similarity index 100% rename from source/fundamentals/atlas-vector-search.txt rename to source/atlas-vector-search.txt diff --git a/source/connect.txt b/source/connect.txt new file mode 100644 index 00000000..606918cc --- /dev/null +++ b/source/connect.txt @@ -0,0 +1,45 @@ +.. _golang-connection-guide: +.. _golang-connection: +.. _golang-connect: + +================ +Connection Guide +================ + +.. facet:: + :name: genre + :values: tutorial + +.. meta:: + :description: Learn how to use the MongoDB Go Driver to connect to MongoDB. + :keywords: connection string, client options, replica set, code example + +.. contents:: On this page + :local: + :backlinks: none + :depth: 2 + :class: singlecol + +.. toctree:: + :titlesonly: + :maxdepth: 1 + + Create a MongoClient + Choose a Connection Target + Connection Options + Connection Troubleshooting + Connect with AWS Lambda + +Overview +-------- + +Learn how to set up a connection and specify connection behavior from your +application to a MongoDB deployment using the {+driver-short+} in the following +sections: + +- :ref:`golang-mongoclient` +- :ref:`golang-connection-options` +- :ref:`golang-connection-troubleshooting` + +For more information about authenticating with a MongoDB instance, see the +:ref:`golang-authentication` section. \ No newline at end of file diff --git a/source/connect/connection-options/cluster-settings.txt b/source/connect/connection-options/cluster-settings.txt new file mode 100644 index 00000000..ff2f043c --- /dev/null +++ b/source/connect/connection-options/cluster-settings.txt @@ -0,0 +1,204 @@ +.. _golang-cluster-settings: + +========================== +Customize Cluster Settings +========================== + +.. contents:: On this page + :local: + :backlinks: none + :depth: 2 + :class: singlecol + +.. facet:: + :name: genre + :values: reference + +.. meta:: + :keywords: code example, connection string, connection options + +Overview +-------- + +In this guide, you can learn how the {+driver-short+} manages clusters and how +to customize the cluster settings. + +Specify Settings +---------------- + +You can specify settings for your clusters by using either a connection string +or a ``ClientOptions`` struct when creating a new ``Client`` +instance. Select the :guilabel:`Connection String` or :guilabel:`ClientOptions` tab to see the +available options. + +.. tabs:: + + .. tab:: Connection String + :tabid: uri + + The following table describes the parameters you can use in your connection + string to modify the driver's behavior when interacting with your MongoDB + cluster: + + .. list-table:: + :header-rows: 1 + :stub-columns: 1 + :widths: 40 60 + + * - Parameter + - Description + + * - ``serverSelectionTimeoutMS`` + - Specifies the maximum amount of time the driver will wait for a server to + be available before throwing an error. + + *Default:* 30 seconds + + * - ``localThresholdMS`` + - Specifies the maximum latency in milliseconds for selecting a server. + + *Default:* 15 milliseconds + + * - ``replicaSet`` + - Specifies the name of the replica set to connect to. + + * - ``directConnection`` + - Specifies whether to connect directly to a single server, bypassing the + replica set or sharded cluster. + + *Default:* ``false`` + + * - ``loadBalanced`` + - Specifies whether the driver is connecting to MongoDB by using a load + balancer. If set to ``true``, the driver assumes that it is + connecting through a load balancer. + + You can set this option to ``true`` only if you meet the following requirements: + + - You specify only one host name + - You aren't connecting to a replica set + - The ``srvMaxHosts`` option is unset or has a value of ``0`` + - The ``directConnection`` option is unset or has a value of ``false`` + + *Default:* ``false`` + + * - ``srvServiceName`` + - Specifies the service name of the `SRV resource records + `__ the driver retrieves to + construct your :manual:`seed list + `. You must use the + :manual:`DNS Seed List Connection Format + ` in + your connection string to use this option. + + .. tab:: ClientOptions + :tabid: options + + The following table describes several methods you can chain to your + ``ClientOptions`` struct to modify the driver's behavior: + + .. list-table:: + :header-rows: 1 + :stub-columns: 1 + :widths: 40 60 + + * - Method + - Description + + * - ``SetServerSelectionTimeout()`` + - Specifies the maximum amount of time the driver will wait for a server to + be available before throwing an error. + + *Default:* 30 seconds + + * - ``SetLocalThreshold()`` + - Specifies the maximum latency in milliseconds for selecting a server. + + *Default:* 15 milliseconds + + * - ``SetReplicaSet()`` + - Specifies the name of the replica set to connect to. + + * - ``SetDirect()`` + - Specifies whether to connect directly to a single server, bypassing the + replica set or sharded cluster. + + *Default:* ``false`` + + * - ``SetLoadBalanced()`` + - Specifies whether the driver is connecting to MongoDB by using a + load balancer. If set to ``true``, the driver assumes that it is + connecting through a load balancer. + + You can set this option to ``true`` only if you meet the following requirements: + + - You specify only one host name + - You aren't connecting to a replica set + - The ``srvMaxHosts`` option is unset or has a value of ``0`` + - The ``directConnection`` option is unset or has a value of ``false`` + + *Default:* ``false`` + + * - ``SetSRVServiceName()`` + - Specifies a custom service name of the `SRV resource records + `__ the driver retrieves to + construct your :manual:`seed list + `. To use a custom SRV + service name in SRV discovery, you must call this function before you + call ``ApplyURI()``. + + To learn more about the available methods, see the :ref:`golang-cluster-settings-resources` section. + +Example +~~~~~~~ + +Select the :guilabel:`Connection String` or :guilabel:`ClientOptions` tab to +see the corresponding example: + +.. tabs:: + + .. tab:: Connection String + :tabid: uriExample + + The following code uses the connection string to configure the maximum + server selection timeout to 10 seconds and the local threshold to 20 + milliseconds: + + .. literalinclude:: /includes/connect/cluster-settings-uri.go + :language: go + :start-after: start-uri-variable + :end-before: end-uri-variable + :dedent: + + The following code creates a client and passes the connection string to the + ``ApplyURI()`` method: + + .. literalinclude:: /includes/connect/cluster-settings-uri.go + :language: go + :start-after: start-apply-uri + :end-before: end-apply-uri + :dedent: + + .. tab:: ClientOptions + :tabid: optionsExample + + The following code creates a client and sets the cluster options with a + maximum server selection timeout of 10 seconds and a local threshold of + 20 milliseconds: + + .. literalinclude:: /includes/connect/cluster-settings-client-options.go + :language: go + :start-after: start-client-options + :end-before: end-client-options + :dedent: + +.. _golang-cluster-settings-resources: + +API Documentation +----------------- + +To learn more about the methods and types in this guide, see the following API documentation: + +- `Client <{+api+}/mongo#Client>`__ +- `ClientOptions <{+api+}/mongo/options#ClientOptions>`__ +- `ApplyURI() <{+api+}/mongo/options#ClientOptions.ApplyURI>`__ \ No newline at end of file diff --git a/source/connect/connection-options/connection-pools.txt b/source/connect/connection-options/connection-pools.txt new file mode 100644 index 00000000..b246d2e6 --- /dev/null +++ b/source/connect/connection-options/connection-pools.txt @@ -0,0 +1,245 @@ +.. _golang-connection-pools: + +================ +Connection Pools +================ + +.. contents:: On this page + :local: + :backlinks: none + :depth: 2 + :class: singlecol + +.. facet:: + :name: genre + :values: reference + +Overview +-------- + +In this guide, you can learn about how the {+driver-short+} uses connection +pools to manage connections to a MongoDB deployment and how you can configure +connection pool settings in your application. + +A connection pool is a cache of open database connections maintained by the +{+driver-short+}. When your application requests a connection to MongoDB, the +{+driver-short+} seamlessly gets a connection from the pool, performs +operations, and returns the connection to the pool for reuse. + +Connection pools help reduce application latency and the number of times new +connections are created by {+driver-short+}. + +.. _golang-faq-connection-pool: + +Create a Connection Pool +------------------------ + +Every ``Client`` instance has a built-in connection pool for each server in your +MongoDB topology. If you do not configure the ``minPoolSize`` option, connection +pools open sockets on demand. These sockets support concurrent MongoDB +operations, or `goroutines `__, in +your application. + +When a new ``Client`` instance is instatiated, it opens two sockets per server +in your MongoDB topology for monitoring the server's state. + +For example, a client connected to a three-node replica set opens six monitoring +sockets. If the application uses the default setting for ``maxPoolSize`` and +only queries the primary (default) node, then there can be at most ``106`` open +sockets and ``100`` connections in the connection pool. If the application uses +a :ref:`read preference ` to query the secondary nodes, their +pools also grow and there can be ``306`` total connections. + +For efficiency, create a client once for each process, and reuse it for all +operations. Avoid creating a new client for each request because this will +increase latency. + +Configure a Connection Pool +--------------------------- + +You can specify settings for your connection pool either by using a connection +string or by using the ``options.Client`` methods. + +Select the :guilabel:`Connection String` or :guilabel:`ClientOptions` tab to +see the corresponding syntax: + +.. tabs:: + + .. tab:: Connection String + :tabid: uri + + The following are connection string settings you can use to configure your + connection pool: + + .. list-table:: + :widths: 25,75 + :header-rows: 1 + + * - Setting + - Description + + * - ``maxPoolSize`` + + - Maximum number of connections opened in the pool. If an operation needs a + new connection while the connection pool has ``maxPoolSize`` connections + open, the new operation waits for a new connection to open. To limit this + waiting time, use the single timeout setting. + + *Default:* ``100`` + + * - ``minPoolSize`` + + - Minimum number of connections opened in the pool. The value of + ``minPoolSize`` must be less than the value of ``maxPoolSize``. + + *Default*: ``0`` + + * - ``maxConnecting`` + + - Maximum number of connections a pool may establish concurrently. + + *Default:* ``2`` + + * - ``maxIdleTimeMS`` + + - The maximum number of milliseconds that a connection can remain idle in + the pool before being removed and closed. + + *Default:* ``None`` (no limit) + + * - ``waitQueueTimeoutMS``` + + - Specifies the maximum wait time in milliseconds that a thread can wait + for a connection to become available. + + *Default*: ``0`` (no limit) + + .. tab:: ClientOptions + :tabid: ClientOptions + + The following table describes the methods you can chain to your settings + to modify the driver's behavior: + + .. list-table:: + :widths: 25,75 + :header-rows: 1 + + * - Setting + - Description + + * - ``SetMaxPoolSize()`` + + - Maximum number of connections opened in the pool. If an operation needs a + new connection while the connection pool has the configured maximum connections + open, the new operation waits for a new connection to open. To limit this + waiting time, use the single timeout setting. + + *Default:* ``100`` + + * - ``SetMinPoolSize()`` + + - Minimum number of connections opened in the pool. The value of + ``MinPoolSize`` must be less than the value of ``MaxPoolSize``. + + *Default*: ``0`` + + * - ``SetMaxConnecting()`` + + - Maximum number of connections a pool may establish concurrently. + + *Default:* ``2`` + + * - ``SetMaxConnIdleTime()`` + + - The maximum number of milliseconds that a connection can remain idle in + the pool before being removed and closed. + + *Default:* ``0`` (no limit) + +Example +~~~~~~~ + +Select the :guilabel:`Connection String` or :guilabel:`ClientOptions` tab to +see the corresponding example: + +.. tabs:: + + .. tab:: Connection String + :tabid: uriExample + + The following code uses the connection string to configure the maximum + connection pool size of ``50``, a minimum pool size of ``10``, and a + maximum idle time of ``30000`` milliseconds (30 seconds): + + .. literalinclude:: /includes/connect/connection-pools-uri.go + :language: go + :start-after: start-uri-variable + :end-before: end-uri-variable + :dedent: + + The following code creates a client and passes the connection string to the + ``ApplyURI()`` method: + + .. literalinclude:: /includes/connect/connection-pools-uri.go + :language: go + :start-after: start-apply-uri + :end-before: end-apply-uri + :dedent: + + .. tab:: ClientOptions + :tabid: optionsExample + + The following code creates a client and sets the connection pool options + with a maximum connection pool size of ``50``, a minimum pool size of + ``10``, and a maximum idle time of ``30000`` milliseconds (30 seconds): + + .. literalinclude:: /includes/connect/connection-pools-client-options.go + :language: go + :start-after: start-client-options + :end-before: end-client-options + :dedent: + +Optimize Connection Pools +------------------------- + +Connection pools are rate-limited such that each connection pool can only create, +at maximum, the value of ``maxConnecting`` connections in parallel at any time. +Any new goroutine stops waiting in the following cases: + +- One of the existing goroutines finishes creating a connection, or an existing + connection is checked back into the pool. +- The driver's ability to reuse existing connections improves due to rate-limits + on connection creation. + +The driver does not limit the number of operations that can wait for sockets to +become available, so it is the application's responsibility to manage its +operation queue. Operations can wait for any length of time unless you define +the ``waitQueueTimeoutMS`` option. + +An operation that waits more than the length of time defined by +``waitQueueTimeoutMS`` for a socket raises a connection error. Use this option +if it is more important to bound the duration of operations during a load spike +than it is to complete every operation. + +Disconnecting +------------- + +When you call ``Client.Disconnect()`` from any goroutine, the driver closes all +idle sockets, and then closes all sockets as they are returned to the pool. + +Additional Information +---------------------- + +For more information on using a connection pool, see the :manual:`Connection +Pool ` documentation in the Server +manual. + +API Documentation +~~~~~~~~~~~~~~~~~ + +To learn more about any of the methods or types discussed in this +guide, see the following API documentation: + +- `Client <{+api+}/mongo#Client>`__ +- `ClientOptions <{+api+}/mongo/options#ClientOptions>`__ +- `Client.Diconnect() <{+api+}/mongo#Client.Disconnect>`__ \ No newline at end of file diff --git a/source/connect/connection-options/csot.txt b/source/connect/connection-options/csot.txt new file mode 100644 index 00000000..5ccf15ea --- /dev/null +++ b/source/connect/connection-options/csot.txt @@ -0,0 +1,237 @@ +.. _golang-timeout-setting: +.. _golang-csot: + +=========================== +Limit Server Execution Time +=========================== + +.. contents:: On this page + :local: + :backlinks: none + :depth: 2 + :class: singlecol + +.. facet:: + :name: genre + :values: reference + +.. meta:: + :keywords: error, blocking, thread, task, code example + +Overview +-------- + +In this guide, you can learn about the single timeout setting in the +{+driver-short+}, also known as the **client-side operation timeout (CSOT)**. + +When you use the {+driver-short+} to perform a server operation, you can also +limit the amount of time in which the server can finish the operation. +The timeout applies to all steps needed to complete the operation, +including server selection, connection checkout, and server-side +execution. When the timeout expires, the {+driver-short+} raises a +timeout exception. + +.. note:: Experimental Feature + + The CSOT feature is experimental and might change in future driver + releases. + +timeoutMS Option +---------------- + +To specify a timeout when connecting to a MongoDB deployment, set the +``timeoutMS`` connection option to the timeout length in milliseconds. You can +set the ``timeoutMS`` option in the following ways: + +- Calling the ``SetTimeout()`` method when + specifying options for your ``Client`` instance +- Setting the ``timeoutMS`` parameter in your connection string + +The following code examples set a client-level timeout of ``200`` milliseconds. +Select the :guilabel:`Client` or :guilabel:`Connection +String` tab to see the corresponding code. + +.. tabs:: + + .. tab:: MongoClientSettings + :tabid: mongoclientsettings + + .. literalinclude:: /includes/connect/csot.go + :language: go + :start-after: start-client-opts + :end-before: end-client-opts + :dedent: + + .. tab:: Connection String + :tabid: connection-string + + .. code-block:: go + :copyable: true + + uri := "/?timeoutMS=200" + client, err := mongo.Connect(options.Client().ApplyURI(uri)) + +.. note:: Retries Under Timeout Specification + + If you set a timeout on your ``Client`` or in an operation-level + Context and the server returns a retryable error, the driver retries the + operation as many times as possible before the timeout expires. + + Once the timeout expires, the driver returns a timeout error. + See the Server manual for more information about :ref:`retryable + reads ` and :manual:`retryable writes + `. + +Accepted Timeout Values +~~~~~~~~~~~~~~~~~~~~~~~ + +The following table describes the timeout behavior corresponding to the +accepted values for ``timeoutMS``: + +.. list-table:: + :header-rows: 1 + :widths: 25 75 + + * - Value + - Behavior + + * - Positive integer + - Sets the timeout to use for operation completion. + + * - ``0`` + - Specifies that operations never time out. + + * - ``null`` or unset + - | Defers the timeout behavior to the following settings: + + - :manual:`waitQueueTimeoutMS ` + - :manual:`socketTimeoutMS ` + - :manual:`wTimeoutMS ` + - :manual:`maxTimeMS ` + + | These settings are deprecated and are ignored if you set ``timeoutMS``. + +If you specify the ``timeoutMS`` option, the driver automatically applies the +specified timeout to each server operation. + +Timeout Inheritance +~~~~~~~~~~~~~~~~~~~ + +By default, all operations in your application inherit the +``Timeout`` option from ``Client`` if you do not set a different timeout +on specific operations in the operation's Context. + +If you set a timeout on a Context passed into an operation, the driver uses +that value for the operation. If you do not specify a Context timeout, +the operation Context derives the timeout from the ``Client`` instance. + +The following table describes how the timeout value is inherited at each level: + +.. list-table:: + :header-rows: 1 + :widths: 30 70 + + * - Level + - Inheritance Description + + * - Operation + - Takes the highest precedence and overrides the timeout + options that you set at any other level. + + * - Transaction + - Takes precedence over the timeout value that you set at the + client level. + + * - Client + - Applies to all databases, collections, sessions, transactions, and + operations within that client that do not otherwise specify a + Context timeout. + +For more information on overrides and specific options, see the following +:ref:`golang-csot-overrides` section. + +.. _golang-csot-overrides: + +Overrides +--------- + +The {+driver-short+} supports various levels of configuration to control the +behavior and performance of database operations. + +You can specify a ``timeoutMS`` option at a more specific level to override the +client-level configuration. The table in the preceding section describes +the levels at which you can specify a timeout setting. This allows you +to customize timeouts based on the needs of individual operations. + +The following example shows how to set an operation-level timeout in a +Context, which takes priority over the client-level timeout: + +.. literalinclude:: /includes/connect/csot.go + :language: go + :start-after: start-override + :end-before: end-override + :dedent: + :emphasize-lines: 9, 12 + +.. _go-csot-transaction: + +Transactions +~~~~~~~~~~~~ + +When you perform a transaction by using the `WithTransaction() +<{+api+}/mongo#Session.WithTransaction>`__ method, you can apply a +timeout to the transaction operations by setting a timeout within the +Context. + +The following code demonstrates how to set a Context timeout when +calling the ``WithTransaction()`` method to perform a transaction: + +.. literalinclude:: /includes/connect/csot.go + :language: go + :start-after: start-txn-context + :end-before: end-txn-context + :dedent: + :emphasize-lines: 1, 4 + +If you do not specify a Context timeout, the driver inherits the timeout +value set on the parent ``Client``. + +You can also pass Context timeouts to the following session +methods: + +- ``AbortTransaction()`` +- ``CommitTransaction()`` +- ``EndSession()`` + +To learn more about transactions, see the :ref:`golang-transactions` +guide. + +.. _go-csot-cursor: + +Cursors +------- + +Cursors offer configurable timeout settings when using the CSOT feature. You can +adjust cursor timeouts by passing Contexts that have timeout +specifications to `Cursor <{+api+}/mongo#Cursor>`__ methods. + +For operations that create cursors, the timeout setting can either limit +the lifetime of the cursor or be applied separately to the original +operation and all subsequent calls. + +For example, if you pass a Context timeout to the ``Cursor.Next()`` +method, the timeout applies to each action to fetch a result document. +If you pass a Context timeout to the ``Cursor.All()`` method, the +timeout applies to the entire lifetime of the cursor. + +To learn more about cursors, see the :ref:`golang-cursor` guide. + +API Documentation +----------------- + +To learn more about using timeouts with the {+driver-short+}, see the following +API documentation: + +- `ClientOptions <{+api+}/mongo/options#ClientOptions>`__ +- `SetTimeout() <{+api+}/mongo/options#ClientOptions.SetTimeout>`__ +- `Context.WithTimeout() `__ diff --git a/source/fundamentals/connections/network-compression.txt b/source/connect/connection-options/network-compression.txt similarity index 100% rename from source/fundamentals/connections/network-compression.txt rename to source/connect/connection-options/network-compression.txt diff --git a/source/fundamentals/stable-api.txt b/source/connect/connection-options/stable-api.txt similarity index 100% rename from source/fundamentals/stable-api.txt rename to source/connect/connection-options/stable-api.txt diff --git a/source/connect/connection-targets.txt b/source/connect/connection-targets.txt new file mode 100644 index 00000000..80e2410a --- /dev/null +++ b/source/connect/connection-targets.txt @@ -0,0 +1,147 @@ +.. _golang-connection-targets: + +========================== +Choose a Connection Target +========================== + +.. meta:: + :keywords: connection string, URI, server, settings, client, load balancing, srv, dns + +.. 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 a ``MongoClient`` +object to connect to different types of MongoDB deployments by using the Go driver. + +.. tip:: + + To see how to create and configure your ``MongoClient`` object, see the :ref:`Create a Mongo Client ` page. + +.. _go-atlas-connection-target: + +Connect to Atlas +---------------- + +To connect to a MongoDB deployment on Atlas, include the following elements +in your connection string: + +- URL of your Atlas cluster +- MongoDB username +- MongoDB password + +Then, pass your connection string to the ``MongoClient`` constructor. + +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:`` +guide. + +The following code shows how you can create a client that uses an Atlas +connection string and the {+stable-api+} version, connect to MongoDB, and +verify that the connection is successful: + +.. _go-connection-example-code: + +.. literalinclude:: /includes/fundamentals/code-snippets/srv.go + :language: go + +.. important:: + + New Serverless instances can no longer be created, and as of May 5 2025, all + existing Serverless instances have been migrated. The `All Clusters + `__ page in the Atlas UI shows which tiers + your instances are migrated to based on usage. See the :ref:`Manage + Serverless Instances ` page to learn more about + how to manually handle existing Serverless instances. + +.. _go-local-connection-target: + +Connect to Local Deployments +---------------------------- + +.. include:: /includes/localhost-connection.rst + +To test whether you can connect to your server, replace the connection +string with your localhost connection string in the preceding :ref:`code example +`. + +.. _go-replica-set-connection-target: + +Connect to Replica Sets +----------------------- + +A MongoDB replica set deployment is a group of connected instances that +store the same set of data. This configuration provides data +redundancy and high data availability. + +To connect to a replica set deployment, specify the hostname and port numbers +of each instance, separated by commas, and the replica set name as the value +of the ``replicaSet`` parameter in the connection string. In the following +example connection string, the hostnames are ``host1``, ``host2``, and ``host3``, and the +port numbers are all ``27017``. The replica set name is ``myRS``. + +.. code-block:: none + + mongodb://host1:27017,host2:27017,host3:27017/?replicaSet=myRS + +When connecting to a replica set, the driver takes the following actions by default: + +- Discovers all replica set members when given the address of any one member. +- Dispatches operations to the appropriate member, such as instructions + to write against the **primary**. + +.. tip:: + + You can specify just one host to connect to a replica set. However, you must + provide the full list of hosts to ensure connectivity when the specified host + is unavailable. + +To learn more about replica sets, see the :manual:`Replication ` +entry in the Server manual. + +.. _go-direct-connection-target: + +Direct Connection +~~~~~~~~~~~~~~~~~ + +To force operations on the host designated in the connection string, +specify the ``directConnection`` option. Direct connections exhibit the +following behavior: + +- They don't support SRV strings. +- They fail on writes when the specified host is not the **primary**. +- They require you to specify a **secondary** node with :ref:`secondary read + preference ` when the specified host isn't the + **primary** node. + +.. note:: Replica Set in Docker + + .. sharedinclude:: dbx/docker-replica-set.rst + +DNS Service Discovery +--------------------- + +.. sharedinclude:: dbx/srv-polling.rst + + .. replacement:: srv-uri + + .. code-block:: go + + uri := "mongodb+srv:///" + +API Documentation +----------------- + +To learn more about connecting to different MongoDB instances with a +``MongoClient``, see the following API Documentation: + + - `MongoClient `__ + - `options `__ + - `connect `__ + - `readPreference `__ diff --git a/source/connection-troubleshooting.txt b/source/connect/connection-troubleshooting.txt similarity index 100% rename from source/connection-troubleshooting.txt rename to source/connect/connection-troubleshooting.txt diff --git a/source/connect/mongoclient.txt b/source/connect/mongoclient.txt new file mode 100644 index 00000000..b2434e12 --- /dev/null +++ b/source/connect/mongoclient.txt @@ -0,0 +1,179 @@ +.. _golang-mongoclient: + +==================== +Create a MongoClient +==================== + +.. contents:: On this page + :local: + :backlinks: none + :depth: 2 + :class: singlecol + +.. facet:: + :name: genre + :values: reference + +.. meta:: + :keywords: connection string, URI, Atlas, code example + +Overview +-------- + +In this guide, you can learn how to connect to a `MongoDB Atlas deployment +`__, a MongoDB instance, or a replica set +using the {+driver-short+}. + +To connect to a MongoDB deployment, you need the following two things: + +- **Connection URI**, also known as a *connection string*, which tells the {+driver-short+} + which MongoDB deployment to connect to. + +- **MongoClient** object, which creates the connection to and performs operations + on the MongoDB deployment. + +You can use ``options.Client()`` to customize the way the {+driver-short+} +behaves while connected to MongoDB. + +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 the :ref:`golang-connection-troubleshooting` guide. + + * - ``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. + When you call ``client.db()`` with no argument, this is the database that is used. 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:`golang-connection-options` for a full description of + these options. + +.. tip:: + + To retrieve a connection string for an Atlas deployment, follow the + :ref:`Quick Start guide `. + +For more information about creating a connection string, see :manual:`Connection +Strings ` in the MongoDB Server documentation. + +.. _golang-usage-examples-env-variable: + +Environment Variable +~~~~~~~~~~~~~~~~~~~~ + +You can access your connection string as an environment variable +by using the following code: + +.. code-block:: go + + uri := os.Getenv("MONGODB_URI") + +You can use `GoDotEnv `__ to define +your environment variable. + +Add the following application configuration in your ``.env`` file at the +root of your project, replacing the placeholders with the values for your +deployment's connection string. To learn more, see the +`GoDotEnv documentation `__. + +.. code-block:: + + MONGODB_URI=mongodb+srv://:@?retryWrites=true&w=majority + +Create a Client to Connect to MongoDB Atlas +------------------------------------------- + +To connect to MongoDB, you must create a client. A client manages your +connections and runs database commands. + +You can create a client that uses your connection string and other client +options by passing a ``ClientOptions`` object to the ``Connect()`` method. + +To specify your connection URI, pass it to the ``ApplyURI()`` method, which +returns a new ``ClientOptions`` instance. To set any other options, call the +relevant helper method from the options package. + +.. tip:: Reuse Your Client with Connection Pools + + We recommend that you reuse your client across sessions and operations by + using a connection pool. You can use the same ``Client`` instance to perform + multiple tasks, instead of creating a new one each time. The ``Client`` type + is safe for concurrent use by multiple `goroutines + `__. To learn more about how connection + pools work in the driver, see the :ref:`golang-connection-pools` guide. + +To learn more about connection options, see the :ref:`Connection Options +` section. To learn more about creating a client, see +the API documentation for `Client <{+api+}/mongo#Client>`__ and `Connect() +<{+api+}/mongo#Connect>`__. + +You can set the {+stable-api+} version as an option to avoid breaking changes +when you upgrade to a new server version. To learn more about the {+stable-api+} +feature, see the :ref:`{+stable-api+} page `. + +.. _go-connection-example-code: + +Example +~~~~~~~ + +The following code shows how you can create a client that uses an Atlas +connection string and the {+stable-api+} version, connects to MongoDB, and verifies +that the connection is successful: + +.. literalinclude:: /includes/fundamentals/code-snippets/srv.go + :language: go + :copyable: + :dedent: + +Additional Resources +-------------------- + +For more information about the concepts in this guide, see the following +documentation: + +- :manual:`Connection Strings ` in the Server + manual +- :manual:`Connection String Options ` in the + Server manual +- :atlas:`Driver Connection ` guide in the Atlas documentation + and select :guilabel:`Go` from the language dropdown + +API Documentation +~~~~~~~~~~~~~~~~~ + +To learn more about the methods and types discussed in this guide, see the +following API Documentation: + +- `Client <{+api+}/mongo#Client>`__ +- `ClientOptions <{+api+}/mongo/options#ClientOptions>`__ diff --git a/source/fundamentals/connections/connection-options.txt b/source/connect/specify-connection-options.txt similarity index 55% rename from source/fundamentals/connections/connection-options.txt rename to source/connect/specify-connection-options.txt index af2537da..d6155c37 100644 --- a/source/fundamentals/connections/connection-options.txt +++ b/source/connect/specify-connection-options.txt @@ -1,8 +1,8 @@ .. _golang-connection-options: -================== -Connection Options -================== +========================== +Specify Connection Options +========================== .. facet:: :name: genre @@ -17,6 +17,17 @@ Connection Options :depth: 2 :class: singlecol +.. toctree:: + :titlesonly: + :maxdepth: 1 + + Specify Connection Options + Compress Network Traffic + Customize Cluster Settings + Stable API + Limit Server Execution Time + Connection Pools + Overview -------- @@ -45,7 +56,9 @@ default value, and a description of the option. - ``null`` - Specifies the number of milliseconds that a single operation run on the ``Client`` can take before returning a timeout error. Operations honor - this setting only if there is no deadline on the operation Context. + this setting only if there is no deadline on the operation + Context. To learn more about this option, see the :ref:`CSOT + ` guide. * - **connectTimeoutMS** - integer @@ -116,82 +129,3 @@ default value, and a description of the option. For a full list of connection options, see the `ClientOptions API documentation <{+api+}/mongo/options#ClientOptions>`__. - -.. _golang-timeout-setting: - -Single Timeout Setting ----------------------- - -You can set a single ``Timeout`` option on your ``Client`` instance to -specify the maximum amount of time that a single operation can take to -execute. - -Set a client-level timeout by calling the ``SetTimeout()`` method when -specifying options for your ``Client`` instance or by specifying the -``timeoutMS`` option in your connection URI. By default, all -``Database``, ``Collection``, ``Session``, ``ChangeStream``, and -``Bucket`` instances elsewhere in your application inherit the -``Timeout`` option from ``Client`` if you do not set a different timeout -on specific operations in the operation's Context. - -If you set a timeout on a Context passed into an operation, the driver uses -that value for the operation. If you do not specify a Context timeout, -the operation Context derives the timeout from the ``Client`` instance. - -.. note:: Retries under Timeout Specification - - If you set a timeout on your ``Client`` or in an operation-level - Context and the server returns a retryable error, the driver retries the - operation as many times as possible before the timeout expires. - - Once the timeout expires, the driver returns a timeout error. - See the Server manual for more information about :ref:`retryable - reads ` and :manual:`retryable writes - `. - -Timeout Examples -~~~~~~~~~~~~~~~~ - -This section provides examples that demonstrate different ways to set a -timeout in your application. - -Client Option -^^^^^^^^^^^^^ - -The following code shows how to set the ``Timeout`` option on a ``Client`` -by using the ``SetTimeout()`` method: - -.. code-block:: go - - opts := options.Client().SetTimeout(5 * time.Second) - client, err := mongo.Connect(opts) - -Connection String Option -^^^^^^^^^^^^^^^^^^^^^^^^ - -The following example shows how to set a single timeout by using the -``timeoutMS`` URI option. Then, the code executes an insert operation -that inherits the timeout: - -.. code-block:: go - :emphasize-lines: 1, 5 - - uri := "mongodb://user:pass@sample.host:27017/?timeoutMS=5000" - client, err := mongo.Connect(options.Client().ApplyURI(uri)) - - ... - coll.InsertOne(context.Background(), doc) - -Operation Timeout -^^^^^^^^^^^^^^^^^ - -The following example shows how to set an operation-level timeout in a -Context, which takes priority over a client-level timeout you might have -set: - -.. code-block:: go - - ctx, cancel := context.WithTimeout(context.TODO(), time.Second) - defer cancel() - - res, err := coll.InsertOne(ctx, bson.D{{"x", 2}}) diff --git a/source/context.txt b/source/context.txt new file mode 100644 index 00000000..56480a5e --- /dev/null +++ b/source/context.txt @@ -0,0 +1,131 @@ +.. _golang-context: + +=============== +Context Package +=============== + +.. facet:: + :name: genre + :values: reference + +.. meta:: + :keywords: code example, unblock + :description: Learn how to use the context package in Go to manage timeouts and cancellations for blocking method calls in the MongoDB Go driver. + +.. contents:: On this page + :local: + :backlinks: none + :depth: 2 + :class: singlecol + +Overview +-------- + +The {+driver-short+} uses the `context package +`__ from the Go standard library to allow +applications to signal timeouts and cancellations for any **blocking method** +call. A blocking method relies on an external event, such as a network +input or output, to proceed with its task. + +An example of a blocking method is the ``InsertOne()`` +method. If you want to perform an insert operation on a ``Collection`` +within 10 seconds, you can use a Context with a timeout. If the +operation doesn't complete within the timeout, the method returns +an error. + +.. code-block:: go + + ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) + defer cancel() + + client.Database("db").Collection("items").InsertOne(ctx, bson.D{{"x",1}}) + +If the Context passed into an operation does not have a deadline, you +can set a ``Timeout`` option on your ``Client`` and the operation +derives the timeout specification from this setting. To learn more +about using the single timeout setting, see the +:ref:`golang-timeout-setting` in the Connection Options guide. + +Expiration +---------- + +The driver considers a Context expired when an operation exceeds its +timeout or is canceled. The driver checks the Context expiration with +the ``Done()`` method. + +The following sections describe when and how the driver checks for +expiration. + +Server Selection +~~~~~~~~~~~~~~~~ + +The driver might block a method call if it can't select a server for +an operation. + +In this scenario, the driver loops until it finds a server to use for the +operation. After each iteration, the driver returns a server selection +timeout error if the Context expired or the selection process took +longer than the ``serverSelectionTimeoutMS`` setting. + +To learn more about how the driver selects a server, see the +:ref:`Read Concern ` section in the Configure +CRUD Operations guide. + +Connection Checkout +~~~~~~~~~~~~~~~~~~~ + +The driver might block a method call if there are no available +connections to check out. + +After selecting a server, the driver tries to check out a connection +from the server's connection pool. If the Context expires while checking +out a connection, the method returns a timeout error. + +Connection Establishment +~~~~~~~~~~~~~~~~~~~~~~~~ + +The driver might block a method call if it must create a new +connection. + +When the driver creates a new connection to perform an operation, the +Context sets a timeout for the establishment process. The driver sets the +timeout to either the Context expiration or connection timeout, whichever is +shorter. + +The following example sets the connection timeout to *1* second and the +Context deadline to *2* seconds. Because the connection timeout is +shorter, the establishment process expires after *1* second. + +.. code-block:: go + :emphasize-lines: 2, 5 + + opts := options.Client() + opts.SetConnectTimeout(1*time.Second) + client, err := mongo.Connect(opts) + + ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second) + defer cancel() + client.Database("").Collection("").InsertOne(ctx, bson.D{{"x",1}}) + +Socket Read and Write +~~~~~~~~~~~~~~~~~~~~~ + +When the driver retrieves a connection for an operation, it sets the +socket's read or write deadline to either the Context deadline or socket +timeout, whichever is shorter. + +If you cancel the Context after the execution of the ``Read()`` or +``Write()`` method but before its deadline, the behavior of the driver +differs based on version. + +The driver generates a separate goroutine to listen for Context +cancellation when the ``Read()`` or ``Write()`` method is in progress. +If the goroutine detects a cancellation, it closes the connection. The +pending ``Read()`` or ``Write()`` method returns an error which the +driver overwrites with the ``context.Canceled`` error. + +.. important:: + + In versions before 1.5.0, the driver doesn't detect the Context + cancellation and waits for the ``Read()`` or ``Write()`` method to + return. diff --git a/source/crud.txt b/source/crud.txt new file mode 100644 index 00000000..e9badd30 --- /dev/null +++ b/source/crud.txt @@ -0,0 +1,34 @@ +.. _golang-crud: + +=============== +CRUD Operations +=============== + +.. meta:: + :description: Explore how to perform CRUD operations using the MongoDB Go Driver, including creating, reading, updating, and deleting documents. + +.. toctree:: + :caption: CRUD Operations + + Insert Documents + Query Documents + Update Documents + Delete Documents + Bulk Write Operations + Transactions + Compound Operations + Configure CRUD Operations + Store Large Files + +CRUD (Create, Read, Update, Delete) operations enable you to work with +data stored in MongoDB. + +- :ref:`golang-insert-guide` +- :ref:`golang-query` +- :ref:`golang-update` +- :ref:`golang-delete` +- :ref:`golang-bulk` +- :ref:`golang-compound-operations` +- :ref:`golang-transactions` +- :ref:`golang-configure-crud` +- :ref:`golang-gridfs` diff --git a/source/fundamentals/crud/write-operations/bulk.txt b/source/crud/bulk.txt similarity index 97% rename from source/fundamentals/crud/write-operations/bulk.txt rename to source/crud/bulk.txt index 9f79301e..a1c3b1bb 100644 --- a/source/fundamentals/crud/write-operations/bulk.txt +++ b/source/crud/bulk.txt @@ -385,6 +385,31 @@ the bulk operation: {"title":"Middlemarch","author":"George Eliot","length":904} {"title":"Pale Fire","author":"Vladimir Nabokov","length":246} +Bulk Operation Example: Full File +--------------------------------- + +.. include:: /includes/usage-examples/example-intro.rst + +The following example is a fully runnable file that performs the following actions: + +- Matches a document in which the ``name`` field value is ``"Cafe Tomato"`` and + replaces it with a new document +- Matches a document in which the ``name`` field value is ``"Cafe Zucchini"`` + and updates the value to ``"Zucchini Land"`` + +.. io-code-block:: + :copyable: true + + .. input:: /includes/usage-examples/code-snippets/bulk.go + :language: go + :dedent: + + .. output:: + :language: none + + Number of documents matched: 2 + Number of documents modified: 2 + .. _golang-bulk-client: Client Bulk Write @@ -747,12 +772,6 @@ The following example performs the following actions in any order: Additional Information ---------------------- -For a runnable example on performing a bulk operation, see -:ref:`golang-bulk-ops-usage-example`. - -Related Operations -~~~~~~~~~~~~~~~~~~ - To learn more about performing the operations mentioned, see the following guides: diff --git a/source/fundamentals/crud/compound-operations.txt b/source/crud/compound-operations.txt similarity index 100% rename from source/fundamentals/crud/compound-operations.txt rename to source/crud/compound-operations.txt diff --git a/source/crud/configure.txt b/source/crud/configure.txt new file mode 100644 index 00000000..f14d19cd --- /dev/null +++ b/source/crud/configure.txt @@ -0,0 +1,628 @@ +.. _golang-configure-crud: + +========================= +Configure CRUD Operations +========================= + +.. contents:: On this page + :local: + :backlinks: none + :depth: 2 + :class: singlecol + +.. facet:: + :name: genre + :values: reference + +.. meta:: + :keywords: insert, update, replace, delete, options, code example + +Overview +-------- + +In this guide, you can learn how to use the {+driver-short+} to configure read +and write operations. + +.. _golang-write-read-pref: + +Read and Write Settings +----------------------- + +You can control how the driver routes read operations by setting a +**read preference**. You can also control how the driver handles data +consistency and durability by setting a **read concern** or **write concern**. +Read concerns specify the level of durability required for the data when +performing read operations, and write concerns specify how the driver waits for +acknowledgement of write operations in a replica set. + +You can set write concern, read concern, and read preference options at +the following levels: + +- Client level, which sets the *default for all operation executions* + unless overridden +- Session level +- Transaction level +- Database level +- Collection level + +The preceding list also indicates the increasing order of precedence of the +option settings. For example, if you set a read concern for a transaction, it +will override a read concern set for the client. + +.. _golang-writeconcern: + +Write Concern +~~~~~~~~~~~~~ + +A write concern describes the number of data-bearing +members in a replica set that must acknowledge a write operation, such +as an insert or update, before the operation returns as successful. +By default, the write operation is successful if only the primary +replica set member acknowledges it. + +Options +``````` + +The {+driver-long+} provides the ``writeconcern`` package, which lets you +specify the write concern for a replica set. Set the write concern by passing an +instance of the ``WriteConcern`` type to the ``SetWriteConcern()`` method. The +``WriteConcern`` type provides the following methods to select common write +concern specifications: + +.. list-table:: + :widths: 25 75 + :header-rows: 1 + + * - Method + - Description + + * - ``Custom()`` + - | The client requests acknowledgement that write operations propagate to + tagged members of a ``mongod`` instance. For more + information, see the :rapid:`Write Concern specification + `. + | + | **Parameter**: ``tag (string)`` + + * - ``Journaled()`` + - | The client requests acknowledgement that the replica set has + written the changes to the on-disk journal. For more information, see the + :rapid:`Write Concern specification `. + | + | **Parameter**: none + + * - ``Majority()`` + - | The client requests acknowledgement that write operations propagate to the + majority of data-bearing voting members. For more information, see the + :rapid:`Write Concern specification + `. + | + | **Parameter**: none + + * - ``Unacknowledged()`` + - | The client requests requests no acknowledgment of write + operations. For more information, see the + :rapid:`Write Concern specification for w: 0 + `. + | + | **Parameter**: none + + * - ``W1()`` + - | The client requests acknowledgement that the replica set has + written the changes to memory on one node, such as the standalone mongod or + the primary in a replica set. For more + information, see the :rapid:`Write Concern specification for w: 1 + `. + | + | **Parameter**: none + +.. tip:: Write Concern Timeout + + You cannot set a timeout on a ``WriteConcern`` instance. Instead, set + the timeout at the operation level by using the ``WithTimeout()`` + method when creating a Context. To learn more, see + :ref:`golang-timeout-setting` in the Connection Options guide. + +If you require a more specialized write concern, you can define a custom +``WriteConcern`` struct literal. You can set the following fields in a +``WriteConcern`` struct: + +.. list-table:: + :widths: 25 75 + :header-rows: 1 + + * - Field + - Description + + * - ``W`` + - | Specifies the number of ``mongod`` instances or tagged members + that write operations must propagate to for acknowledgement. Common values include + ``1``, ``0``, and ``"majority"``. + | + | **Type**: ``string`` or ``int`` + + * - ``Journal`` + - | Specifies whether the replica set must write the changes to the on-disk + journal for acknowledgement. + | + | **Type**: ``bool`` + +.. tip:: + + Alternatively, you can specify a write concern in your connection + string. See the :manual:`Server manual entry on Write Concern Options + ` for more information. + +Example +``````` + +The following code shows how you can specify different write concerns +at the client and collection level. The client-level write concern +requests acknowledgement from two replica set members and sets journaling to +``false``. The collection-level write concern requests +acknowledgement from the majority of replica set members. + +.. code-block:: go + :emphasize-lines: 2-7,11-12 + + uri := "mongodb://:" + journal := false + cliWC := &writeconcern.WriteConcern{ + W: 2, + Journal: &journal, + } + clOpts := options.Client().ApplyURI(uri).SetWriteConcern(cliWC) + client, err := mongo.Connect(clOpts) + ... + + collWC := writeconcern.Majority() + collOpts := options.Collection().SetWriteConcern(collWC) + coll := client.Database("db").Collection("myColl", collOpts) + +.. _golang-readconcern: + +Read Concern +~~~~~~~~~~~~ + +The read concern option allows you to determine which data the client +returns from a query. The default read concern level is "local", meaning +that the client returns the instance’s most recent data, with no guarantee that +the data has been written to a majority of the replica set members. + +Options +``````` + +The {+driver-long+} provides the ``readconcern`` package, which lets you specify +the read concern for a replica set. Set the read concern by passing an instance +of a ``ReadConcern`` type to the ``SetReadConcern()`` method. The +``ReadConcern`` type has the following methods to specify the read concern: + +.. list-table:: + :widths: 25 75 + :header-rows: 1 + + * - Method + - Description + + * - ``Available()`` + - The query returns data from the instance + with no guarantee that the data has been written to a majority of + the replica set members. For more information, see the + :rapid:`Read Concern specification `. + + * - ``Linearizable()`` + - The query returns data that reflects all + successful writes issued with a write concern of ``majority`` and + acknowledged before the read operation begins. For more information, see the + :rapid:`Read Concern specification `. + + * - ``Local()`` + - The query returns the instance’s most recent + data. For more information, see the + :rapid:`Read Concern specification `. + + * - ``Majority()`` + - The query returns the instance’s most recent + data acknowledged as having been written to a majority of members + in the replica set. For more information, see the + :rapid:`Read Concern specification `. + + * - ``Snapshot()`` + - The query returns a complete copy of the + data in a ``mongod`` instance at a specific point in time. This option is + available only for operations within multi-document transactions. For more information, see the + :rapid:`Read Concern specification `. + +Example +``````` + +The following code shows how you can specify a read concern of +"majority". The code then selects a ``Collection`` +with this option. + +.. code-block:: go + :emphasize-lines: 1-2 + + rc := readconcern.Majority() + opts := options.Collection().SetReadConcern(rc) + database := client.Database("db") + coll := database.Collection("myCollection", opts) + +.. _golang-read-pref: + +Read Preference +~~~~~~~~~~~~~~~ + +The read preference option specifies how the MongoDB client routes read +operations to the members of a replica set. By default, an application +directs its read operations to the primary member in a replica set. + +Read preference consists of the read preference mode and, optionally, a +:rapid:`tag set list `, the +:rapid:`maxStalenessSeconds ` option, and the +:rapid:`hedged read ` option. + +Options +``````` + +The {+driver-long+} provides the ``readpref`` package, which lets you specify +the read preference for a replica set. Set the read preference by passing an +instance of the ``ReadPref`` type to the ``SetReadPreference()`` method. The +``ReadPref`` type has the following methods to specify the read preference: + +.. list-table:: + :widths: 25 75 + :header-rows: 1 + + * - Method + - Description + + * - ``Nearest()`` + - The client reads from a random eligible replica set member, + based on a specified latency threshold. For more information, see the + :rapid:`Read Preference Server manual entry `. + + * - ``Primary()`` + - The client reads from the current replica set primary node. For more information, see the + :rapid:`Read Preference Server manual entry `. + + * - ``PrimaryPreferred()`` + - The client reads from the primary node if it's available. If the primary is + unavailable, operations read from secondary members. For more + information, see the :rapid:`Read Preference Server manual entry `. + + * - ``Secondary()`` + - The client reads from the secondary members of the replica set. For more information, see the + :rapid:`Read Preference Server manual entry `. + + * - ``SecondaryPreferred()`` + - The client reads from the secondary nodes if one or more is available. If the secondaries are + unavailable, operations read from the primary member. For more information, see the + :rapid:`Read Preference Server manual entry `. + +.. tip:: + + Alternatively, you can specify a read preference in your connection + string. See the :manual:`Server manual entry on Read Preference + Options ` for + more information. + +Example +``````` + +The following code shows how you can specify a read preference to read +from secondary nodes. The code then selects a ``Database`` +with this option. + +.. code-block:: go + :emphasize-lines: 1-2 + + rp := readpref.Secondary() + opts := options.Database().SetReadPreference(rp) + database := client.Database("db", opts) + +Retryable Reads and Writes +-------------------------- + +The {+driver-short+} automatically retries certain read and write operations a single time +if they fail due to a network or server error. + +You can explicitly disable retryable reads or retryable writes by setting the +``RetryReads`` or ``RetryWrites`` option to ``False`` when creating a new client +by using the ``options.Client`` struct. + +The following example disables retryable reads and writes for a client by using +the ``ClientOptions`` setter functions: + +.. literalinclude:: /includes/fundamentals/code-snippets/CRUD/retryableReadsWrites.go + :start-after: start-retryable-example + :end-before: end-retryable-example + :language: go + :dedent: + +To learn more about supported retryable read operations, see :manual:`Retryable Reads ` +in the {+mdb-server+} manual. To learn more about supported retryable write +operations, see :manual:`Retryable Writes ` in the {+mdb-server+} manual. + +Collation +--------- + +You can specify a **collation** to modify the behavior of read +and write operations. A collation is a set of language-specific rules for string +comparison, such as for letter case and accent marks. + +By default, MongoDB sorts strings using *binary collation*. This default +collation uses the :wikipedia:`ASCII standard ` +character values to compare and order strings. Languages and locales +have specific character-ordering conventions that differ from the ASCII +standard, and you can choose to apply a different set of collation rules +to your operation. + +You can specify a collation at the following levels: + +- Collection: Sets the default collation for operations on the collection. + You cannot define a collation for an existing collection. + +- Index: Sets the collation for operations that use the index. + +- Operation: Sets the operation's collation and overrides any inherited collations. + +Specify a Collation +~~~~~~~~~~~~~~~~~~~ + +To specify a collation, create a ``Collation`` object. You must define the ``Locale`` field +of the ``Collation`` object, but all other fields are optional. For example, the following code +example specifies a ``Collation`` object with the ``"en_US"`` locale collation: + +.. code-block:: go + + myCollation := &options.Collation{Locale: "en_US"} + +For a complete list of ``Collation`` object fields, visit the `Collation API documentation +<{+api+}/mongo/options#Collation>`__. To see all the supported locales and the +default values for the ``Locale`` fields, visit :manual:`Supported Languages and Locales +`. + +Set a Collation on a Collection or View +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +You can apply a collation when you create a new collection or view. This defines the default +collation for any operations called on that collection or view. Set a collation through a +``CreateCollectionOptions`` or ``CreateViewOptions`` object. Then, call the +``CreateCollection()`` or ``CreateView()`` method with your options object as an argument. + +.. _golang-create-collection: + +Create a Collection Example +```````````````````````````` + +The following example creates a new collection called ``books`` and specifies a default +collation with the ``"fr"`` locale. The ``Strength`` collation field has a value of ``1`` +to ignore differences in letter accents. + +.. code-block:: go + + myCollation := &options.Collation{Locale: "fr", Strength: 1} + opts := options.CreateCollection().SetCollation(myCollation) + err := db.CreateCollection(context.TODO(), "books", opts) + + if err != nil { + panic(err) + } + +Use the Default Collation Example +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +If you call an operation that uses a collation on the ``books`` collection, the operation +uses the default collation specified in the :ref:`golang-create-collection`. + +Assume the ``books`` collection contains the following documents: + +.. code-block:: json + + {"name" : "Emma", "length" : "474"} + {"name" : "Les Misérables", "length": "1462"} + {"name" : "Infinite Jest", "length" : "1104"} + {"name" : "Cryptonomicon", "length" : "918"} + {"name" : "Ça", "length" : "1138"} + +.. note:: + + To learn how to insert documents, see :ref:`golang-insert-guide`. + +The following example uses the ``Find()`` method to return all documents with a ``name`` value +that alphabetically precedes ``"Infinite Jest"``: + +.. io-code-block:: + :copyable: true + + .. input:: + :language: go + + filter := bson.D{{"name", bson.D{{"$lt", "Infinite Jest"}}}} + cursor, err := coll.Find(context.TODO(), filter) + if err != nil { + panic(err) + } + + var results []bson.D + if err = cursor.All(context.TODO(), &results); err != nil { + panic(err) + } + + for _, result := range results { + res, _ := bson.MarshalExtJSON(result, false, false) + fmt.Println(string(res)) + } + + .. output:: + :language: none + :visible: false + + {"name":"Emma","length":"474"} + {"name":"Cryptonomicon","length":"918"} + {"name":"Ça","length":"1138"} + +If the code doesn't specify a default ``books`` collation, the ``Find()`` method +follows default binary collation rules to determine the ``name`` values +that precede ``"Infinite Jest"``. These rules place words beginning with "Ç" +after those beginning with "I". The output resembles the following: + +.. code-block:: json + :copyable: false + + {"name":"Emma","length":"474"} + {"name":"Cryptonomicon","length":"918"} + +To learn more about the ``Find()`` method, see :ref:`golang-retrieve`. + +Set a Collation on an Index +~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +You can apply a collation when you create a new index on a collection. The index stores +an ordered representation of the documents in the collection, so your MongoDB instance +doesn't perform the ordering for sorting operations in-memory. + +To use the index in an operation, your operation must use the same collation as the one +specified in the index. Additionally, ensure that the operation is covered by the index that +contains the collation. Set a collation through an ``IndexOptions`` object and pass this object +as an argument to the ``CreateOne()`` method. + +Example +```````` + +After creating the ``books`` collection and applying a default collation, as shown in the +:ref:`golang-create-collection` section, you cannot change the collection's default collation. +However, you can create an index for the collection with a different collation. + +The following example uses the ``CreateOne()`` method to create an ascending index on the +``name`` field and specifies a new collation with an ``"en_US"`` locale: + +.. io-code-block:: + :copyable: true + + .. input:: + :language: go + + myCollation := &options.Collation{Locale: "en_US"} + opts := options.Index().SetCollation(myCollation) + + indexModel := mongo.IndexModel{ + Keys: bson.D{{"name", 1}}, + Options: opts, + } + + name, err := coll.Indexes().CreateOne(context.TODO(), indexModel) + if err != nil { + panic(err) + } + fmt.Println("Name of Index Created: " + name) + + .. output:: + :language: none + :visible: false + + Name of Index Created: name_1 + +.. _golang-op-collation: + +Set a Collation on an Operation +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Operations that read, update, and delete documents from a collection can use collations. +Applying a collation to an operation overrides any default collation previously defined +for a collection. + +If you apply a new collation to an operation that differs from an index's collation, +you cannot use that index. As a result, the operation may not perform as well as one +that is covered by an index. For more information on the disadvantages of sorting operations +not covered by an index, see :manual:`Using Indexes to Sort Query Results `. +See the :manual:`MongoDB manual ` for a list of +operations that support collation. + +Example +``````` + +You can use operations that support collation to update and query documents in the +``books`` collection. + +The following example uses the ``Find()`` method to return documents in which the ``length`` +value is greater than ``"1000"``. The ``NumericOrdering`` collation field has a value of +``true`` to ensure that values are sorted in numerical order rather than alphabetical +order: + +.. io-code-block:: + :copyable: true + + .. input:: + :language: go + + filter := bson.D{{"length", bson.D{{"$gt", "1000"}}}} + myCollation := &options.Collation{Locale: "en_US", NumericOrdering: true} + opts := options.Find().SetCollation(myCollation) + + cursor, err := coll.Find(context.TODO(), filter, opts) + if err != nil { + panic(err) + } + + var results []bson.D + if err = cursor.All(context.TODO(), &results); err != nil { + panic(err) + } + + for _, result := range results { + res, _ := bson.MarshalExtJSON(result, false, false) + fmt.Println(string(res)) + } + + .. output:: + :language: none + :visible: false + + {"name":"Les Misérables","length":"1462"} + {"name":"Infinite Jest","length":"1104"} + {"name":"Ça","length":"1138"} + +If the code doesn't specify a collation with a ``NumericOrdering`` field set to +``true``, the same ``Find()`` operation compares ``length`` values as +strings. In this case, the output resembles the following: + +.. code-block:: json + :copyable: false + + {"name":"Emma","length":"474"} + {"name":"Les Misérables","length":"1462"} + {""name":"Infinite Jest","length":"1104"} + {"name":"Cryptonomicon","length":"918"} + {"name":"Ça","length":"1138"} + +Additional Information +---------------------- + +To learn more about the ``Find()`` method, see the :ref:`golang-retrieve` guide. + +To learn more about the concepts discussed in this guide, visit the following manual pages: + +- :manual:`Read Preference ` +- :manual:`Read Concern ` +- :manual:`Write Concern ` +- :manual:`Collation ` +- :manual:`Collation Locales and Default Parameters ` + +API Documentation +~~~~~~~~~~~~~~~~~ + +To learn more about the methods discussed in this guide, see the following +API Documentation: + +- `WriteConcern <{+api+}/mongo/writeconcern#WriteConcern>`__ +- `ReadConcern <{+api+}/mongo/readconcern#ReadConcern>`__ +- `ReadPref <{+api+}/mongo/readpref#ReadPref>`__ +- `Collation <{+api+}/mongo/options#Collation>`__ +- `CreateCollectionOptions <{+api+}/mongo/options#CreateCollectionOptions>`__ +- `IndexModel <{+api+}/mongo#IndexModel>`__ +- `CreateOne() <{+api+}/mongo#IndexView.CreateOne>`__ +- `IndexOptions <{+api+}/mongo/options#IndexOptions>`__ +- `UpdateOneOptions <{+api+}/mongo/options#UpdateOneOptions>`__ +- `UpdateManyOptions <{+api+}/mongo/options#UpdateManyOptions>`__ \ No newline at end of file diff --git a/source/fundamentals/crud/write-operations/delete.txt b/source/crud/delete.txt similarity index 99% rename from source/fundamentals/crud/write-operations/delete.txt rename to source/crud/delete.txt index 2d075d50..aeaecefd 100644 --- a/source/fundamentals/crud/write-operations/delete.txt +++ b/source/crud/delete.txt @@ -1,4 +1,5 @@ .. _golang-delete-guide: +.. _golang-delete: ================ Delete Documents diff --git a/source/fundamentals/gridfs.txt b/source/crud/gridfs.txt similarity index 100% rename from source/fundamentals/gridfs.txt rename to source/crud/gridfs.txt diff --git a/source/fundamentals/crud/write-operations/insert.txt b/source/crud/insert.txt similarity index 99% rename from source/fundamentals/crud/write-operations/insert.txt rename to source/crud/insert.txt index 581d8326..6ce815b7 100644 --- a/source/fundamentals/crud/write-operations/insert.txt +++ b/source/crud/insert.txt @@ -1,8 +1,8 @@ .. _golang-insert-guide: -================= -Insert a Document -================= +================ +Insert Documents +================ .. facet:: :name: genre diff --git a/source/crud/query.txt b/source/crud/query.txt new file mode 100644 index 00000000..f2ec0906 --- /dev/null +++ b/source/crud/query.txt @@ -0,0 +1,17 @@ +================ +Query Operations +================ + +.. toctree:: + :titlesonly: + :maxdepth: 1 + + Specify a Query + Find Documents + Access Data from a Cursor + Specify Documents to Return + Specify Fields to Return + Count Documents + Distinct Field Values + Search Text + Geospatial Queries diff --git a/source/fundamentals/crud/read-operations/count.txt b/source/crud/query/count.txt similarity index 100% rename from source/fundamentals/crud/read-operations/count.txt rename to source/crud/query/count.txt diff --git a/source/fundamentals/crud/read-operations/cursor.txt b/source/crud/query/cursor.txt similarity index 100% rename from source/fundamentals/crud/read-operations/cursor.txt rename to source/crud/query/cursor.txt diff --git a/source/fundamentals/crud/read-operations/distinct.txt b/source/crud/query/distinct.txt similarity index 100% rename from source/fundamentals/crud/read-operations/distinct.txt rename to source/crud/query/distinct.txt diff --git a/source/fundamentals/geo.txt b/source/crud/query/geo.txt similarity index 100% rename from source/fundamentals/geo.txt rename to source/crud/query/geo.txt diff --git a/source/fundamentals/crud/read-operations/project.txt b/source/crud/query/project.txt similarity index 100% rename from source/fundamentals/crud/read-operations/project.txt rename to source/crud/query/project.txt diff --git a/source/fundamentals/crud/read-operations/query-document.txt b/source/crud/query/query-document.txt similarity index 99% rename from source/fundamentals/crud/read-operations/query-document.txt rename to source/crud/query/query-document.txt index 18c3bac0..ad0f684f 100644 --- a/source/fundamentals/crud/read-operations/query-document.txt +++ b/source/crud/query/query-document.txt @@ -1,4 +1,6 @@ .. _golang-query-document: +.. _golang-query: +.. _golang-crud-read-operations: =============== Specify a Query diff --git a/source/fundamentals/crud/read-operations/retrieve.txt b/source/crud/query/retrieve.txt similarity index 95% rename from source/fundamentals/crud/read-operations/retrieve.txt rename to source/crud/query/retrieve.txt index 48fc0d30..ae6603f3 100644 --- a/source/fundamentals/crud/read-operations/retrieve.txt +++ b/source/crud/query/retrieve.txt @@ -1,7 +1,8 @@ .. _golang-retrieve: +.. _golang-find-one: ============== -Retrieve Data +Find Documents ============== .. meta:: @@ -59,6 +60,8 @@ Find Operations Use **find operations** to retrieve data from MongoDB. Find operations consist of the ``Find()`` and ``FindOne()`` methods. +.. _golang-find-example: + Find All Documents ~~~~~~~~~~~~~~~~~~ @@ -66,72 +69,6 @@ The ``Find()`` method expects you to pass a ``Context`` type and a query filter. The method returns *all* documents that match the filter as a ``Cursor`` type. -For an example that uses the ``Find()`` method, see the :ref:`golang-find-example` -section of this page. To learn how to access data by using a cursor, see -the :ref:`golang-cursor` guide. - -Find One Document -~~~~~~~~~~~~~~~~~ - -The ``FindOne()`` method expects you to pass a ``Context`` type and a -query filter. The method returns *the first document* that matches the -filter as a ``SingleResult`` type. - -For an example that uses the ``FindOne()`` method, see the -:ref:`golang-find-one-example` section of this page. For an example that -uses ``FindOne()`` and queries by using a specific ``ObjectId`` value, see -the :ref:`golang-find-one-by-id` section of this page. - -To learn how to access data from a ``SingleResult`` type, see -:ref:`golang-bson-unmarshalling` in the BSON guide. - -.. _golang-retrieve-options: - -Modify Behavior -~~~~~~~~~~~~~~~ - -You can modify the behavior of ``Find()`` and ``FindOne()`` by passing -in a ``FindOptions`` and ``FindOneOptions`` type respectively. If you -don't specify any options, the driver uses the default values for each -option. - -You can configure the commonly used options in both types with the -following methods: - -.. list-table:: - :widths: 30 70 - :header-rows: 1 - - * - Method - - Description - - * - ``SetCollation()`` - - | The type of language collation to use when sorting results. - | Default: ``nil`` - - * - ``SetLimit()`` - - | The maximum number of documents to return. - | Default: ``0`` - | This option is not available for ``FindOneOptions``. The - ``FindOne()`` method internally uses ``SetLimit(-1)``. - - * - ``SetProjection()`` - - | The fields to include in the returned documents. - | Default: ``nil`` - - * - ``SetSkip()`` - - | The number of documents to skip. - | Default: ``0`` - - * - ``SetSort()`` - - | The field and type of sort to order the matched documents. You can specify an ascending or descending sort. - | Default: none - -.. _golang-find-example: - -Find Example -```````````` - The following example passes a context, filter, and ``FindOptions`` to the ``Find()`` method, which performs the following actions: @@ -155,10 +92,16 @@ the ``Find()`` method, which performs the following actions: {"item":"Sencha","rating":7,"date_ordered":"2009-11-18T05:00:00Z"} {"item":"Masala","rating":8,"date_ordered":"2009-12-01T05:00:00Z"} +To learn how to access data by using a cursor, see the :ref:`golang-cursor` guide. + .. _golang-find-one-example: -Find One Example -```````````````` +Find One Document +~~~~~~~~~~~~~~~~~ + +The ``FindOne()`` method expects you to pass a ``Context`` type and a +query filter. The method returns *the first document* that matches the +filter as a ``SingleResult`` type. The following example passes a context, filter, and ``FindOneOptions`` to the ``FindOne()`` method, which performs the following actions: @@ -182,6 +125,13 @@ to the ``FindOne()`` method, which performs the following actions: {"item":"Masala","rating":9,"date_ordered":"2009-11-12T05:00:00Z"} +For an example that +uses ``FindOne()`` and queries by using a specific ``ObjectId`` value, see +the :ref:`golang-find-one-by-id` section of this page. + +To learn how to access data from a ``SingleResult`` type, see +:ref:`golang-bson-unmarshalling` in the BSON guide. + .. _golang-find-one-by-id: Find One by ObjectId Example @@ -232,6 +182,48 @@ as parameters to the ``FindOne()`` method to perform the following actions: about the ``_id`` field, see the :ref:`_id Field ` section of the Insert a Document page. +.. _golang-retrieve-options: + +Modify Behavior +~~~~~~~~~~~~~~~ + +You can modify the behavior of ``Find()`` and ``FindOne()`` by passing +a ``FindOptions`` or ``FindOneOptions`` instance. If you +don't specify any options, the driver uses the default values for each +option. + +You can configure the commonly used options in both types with the +following methods: + +.. list-table:: + :widths: 30 70 + :header-rows: 1 + + * - Method + - Description + + * - ``SetCollation()`` + - | The type of language collation to use when sorting results. + | Default: ``nil`` + + * - ``SetLimit()`` + - | The maximum number of documents to return. + | Default: ``0`` + | This option is not available for ``FindOneOptions``. The + ``FindOne()`` method internally uses ``SetLimit(-1)``. + + * - ``SetProjection()`` + - | The fields to include in the returned documents. + | Default: ``nil`` + + * - ``SetSkip()`` + - | The number of documents to skip. + | Default: ``0`` + + * - ``SetSort()`` + - | The field and type of sort to order the matched documents. You can specify an ascending or descending sort. + | Default: none + .. _golang-retrieve-aggregation: Aggregation Operations diff --git a/source/crud/query/specify-return-documents.txt b/source/crud/query/specify-return-documents.txt new file mode 100644 index 00000000..89c4e30f --- /dev/null +++ b/source/crud/query/specify-return-documents.txt @@ -0,0 +1,525 @@ +.. _golang-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: + +- ``SetSort()``: Specifies the sort order for the returned documents. +- ``SetSkip()``: Specifies the number of documents to skip before returning query results. +- ``SetLimit()``: Specifies the maximum number of documents to return from a query. + +Sample Data +~~~~~~~~~~~ + +The examples in this guide use the following ``Course`` struct as a model for documents +in the ``courses`` collection: + +.. literalinclude:: /includes/fundamentals/code-snippets/CRUD/sort.go + :start-after: start-course-struct + :end-before: end-course-struct + :language: go + :dedent: + +To run the examples in this guide, load the sample data into the +``db.courses`` collection by using the following snippet: + +.. literalinclude:: /includes/fundamentals/code-snippets/CRUD/sort.go + :language: go + :dedent: + :start-after: begin insertDocs + :end-before: end insertDocs + +.. include:: /includes/fundamentals/automatic-db-coll-creation.rst + +Each document represents a description of a university course and +includes the course title and maximum enrollment, corresponding to +the ``title`` and ``enrollment`` fields in each document. + +.. _golang-sort-results: + +Sort +---- + +To specify the order of your results, pass an interface specifying the +sort fields and direction to the ``SetSort()`` method of an operation's options. + +The following operations take ``SetSort()`` as an option: + +- ``Find()`` +- ``FindOne()`` +- ``FindOneAndDelete()`` +- ``FindOneAndUpdate()`` +- ``FindOneAndReplace()`` +- ``GridFSBucket.Find()`` + +You can set an **ascending** or **descending** sort direction. + +Ascending +~~~~~~~~~ + +An ascending sort orders your results from smallest to largest. To +specify this sort, pass the field you want to sort by and ``1`` to the +``SetSort()`` method. + +.. tip:: + + With an ascending sort, the method orders values of type + ``Boolean`` from ``false`` to ``true``, ``String`` type values + from a to z and numeric type values from negative infinity to + positive infinity. + +The following example specifies an ascending sort on the ``enrollment`` field: + +.. io-code-block:: + :copyable: true + + .. input:: + :language: go + + filter := bson.D{} + opts := options.Find().SetSort(bson.D{{"enrollment", 1}}) + + cursor, err := coll.Find(context.TODO(), filter, opts) + + var results []Course + if err = cursor.All(context.TODO(), &results); err != nil { + panic(err) + } + for _, result := range results { + res, _ := bson.MarshalExtJSON(result, false, false) + fmt.Println(string(res)) + } + + .. output:: + :language: none + :visible: false + + {"title":"Modern Poetry","enrollment":12} + {"title":"World Fiction","enrollment":35} + {"title":"Plate Tectonics","enrollment":35} + {"title":"Abstract Algebra","enrollment":60} + +Descending +~~~~~~~~~~ + +A descending sort orders your results from largest to smallest. To +specify this sort, pass the field you want to sort by and ``-1`` to the +``SetSort()`` method. + +.. tip:: + + With an descending sort, the method orders values of type + ``Boolean`` from ``true`` to ``false``, ``String`` type values + from z to a and numeric type values from positive infinity to + negative infinity. + +The following example specifies a descending sort on the ``enrollment`` field: + +.. io-code-block:: + :copyable: true + + .. input:: + :language: go + + filter := bson.D{} + opts := options.Find().SetSort(bson.D{{"enrollment", -1}}) + + cursor, err := coll.Find(context.TODO(), filter, opts) + + var results []Course + if err = cursor.All(context.TODO(), &results); err != nil { + panic(err) + } + for _, result := range results { + res, _ := bson.MarshalExtJSON(result, false, false) + fmt.Println(string(res)) + } + + .. output:: + :language: none + :visible: false + + {"title":"Abstract Algebra","enrollment":60} + {"title":"World Fiction","enrollment":35} + {"title":"Plate Tectonics","enrollment":35} + {"title":"Modern Poetry","enrollment":12} + +Handling Ties +~~~~~~~~~~~~~ + +A tie occurs when two or more documents have identical values in the +field you are using to sort your results. MongoDB does not guarantee +order if ties occur. + +For example, in the sample data, there is a tie for ``enrollment`` in +the following documents: + +.. code-block:: none + :copyable: false + + {"title":"World Fiction","enrollment":35} + {"title":"Plate Tectonics","enrollment":35} + +You can sort on additional fields to resolve ties in the original sort. +If you want to guarantee a specific order for documents, select sort fields +that do not result in ties. + +The following example specifies a descending sort on the ``enrollment`` field, +then an ascending sort on the ``title`` field: + +.. io-code-block:: + :copyable: true + + .. input:: + :language: go + + + filter := bson.D{} + opts := options.Find().SetSort(bson.D{{"enrollment", -1}, {"title", 1}}) + + cursor, err := coll.Find(context.TODO(), filter, opts) + + var results []Course + if err = cursor.All(context.TODO(), &results); err != nil { + panic(err) + } + for _, result := range results { + res, _ := bson.MarshalExtJSON(result, false, false) + fmt.Println(string(res)) + } + + .. output:: + :language: none + :visible: false + + {"title":"Abstract Algebra","enrollment":60} + {"title":"Plate Tectonics","enrollment":35} + {"title":"World Fiction","enrollment":35} + {"title":"Modern Poetry","enrollment":12} + +Aggregation +~~~~~~~~~~~ + +You can also include the :manual:`$sort ` +stage to specify a sort in an aggregation pipeline. + +The following example specifies a descending sort on the ``enrollment`` +field, then an ascending sort on the ``title`` field: + +.. io-code-block:: + :copyable: true + + .. input:: + :language: go + + sortStage := bson.D{{"$sort", bson.D{{"enrollment", -1}, {"title", 1}}}} + + cursor, err := coll.Aggregate(context.TODO(), mongo.Pipeline{sortStage}) + if err != nil { + panic(err) + } + + var results []Course + if err = cursor.All(context.TODO(), &results); err != nil { + panic(err) + } + for _, result := range results { + res, _ := bson.MarshalExtJSON(result, false, false) + fmt.Println(string(res)) + } + + .. output:: + :language: none + :visible: false + + {"title":"Abstract Algebra","enrollment":60} + {"title":"Plate Tectonics","enrollment":35} + {"title":"World Fiction","enrollment":35} + {"title":"Modern Poetry","enrollment":12} + +.. _golang-skip: + +Skip +---- + +To skip a specified number of returned results from a query, pass the +number of documents you want to skip to the ``SetSkip()`` method of +the read operation's options. + +The following read operations take ``SetSkip()`` as an option: + +- ``Find()`` +- ``FindOne()`` +- ``CountDocuments()`` +- ``GridFSBucket.Find()`` + +If the number of documents exceeds the number of matched documents for a +query, that query returns no documents. + +Find operations return documents in a natural order that is not sorted +on any field. To avoid skipping random documents, use the ``SetSort()`` +method to sort documents on a field with unique values before setting a +skip option. + +The following example performs a ``Find()`` operation with the following +behavior: + +- Sorts the results in ascending order on the ``enrollment`` field +- Skips the first two documents + +.. io-code-block:: + :copyable: true + + .. input:: + :language: go + + opts := options.Find().SetSort(bson.D{{"enrollment", 1}}).SetSkip(2) + + cursor, err := coll.Find(context.TODO(), bson.D{}, opts) + + var results []Course + if err = cursor.All(context.TODO(), &results); err != nil { + panic(err) + } + for _, result := range results { + res, _ := bson.MarshalExtJSON(result, false, false) + fmt.Println(string(res)) + } + + .. output:: + :language: none + :visible: false + + {"title":"Plate Tectonics","enrollment":35} + {"title":"Abstract Algebra","enrollment":60} + +.. _golang-skip-aggregation: + +Aggregation +~~~~~~~~~~~ + +You can also include the :manual:`$skip ` +stage in an aggregation pipeline to skip documents. + +The following example performs an ``Aggregate()`` operation with the following +behavior: + +- Sorts the results in descending order on the ``enrollment`` field +- Skips the first document + +.. io-code-block:: + :copyable: true + + .. input:: + :language: go + + sortStage := bson.D{{"$sort", bson.D{{"enrollment", -1}}}} + skipStage := bson.D{{"$skip", 1}} + + cursor, err := coll.Aggregate(context.TODO(), mongo.Pipeline{sortStage, skipStage}) + if err != nil { + panic(err) + } + + var results []Course + if err = cursor.All(context.TODO(), &results); err != nil { + panic(err) + } + for _, result := range results { + res, _ := bson.MarshalExtJSON(result, false, false) + fmt.Println(string(res)) + } + + .. output:: + :language: none + :visible: false + + {"title":"Plate Tectonics","enrollment":35} + {"title":"World Fiction","enrollment":35} + {"title":"Modern Poetry","enrollment":12} + +.. _golang-limit: + +Limit +----- + +To limit the number of documents returned from a query, pass the +number of documents you want returned to the ``SetLimit()`` method of +the read operation's options. + +The following read operations take ``SetLimit()`` as an option: + +- ``Find()`` +- ``CountDocuments()`` +- ``GridFSBucket.Find()`` + +If the limit is ``0`` or exceeds the number of matched +documents, the method returns all the documents. If the limit is a +negative number, the method uses the absolute value of the negative +number as the limit and closes the cursor after retrieving +documents. + +The following example shows how to return two documents that have an +``enrollment`` field value greater than 20: + +.. io-code-block:: + :copyable: true + + .. input:: + :language: go + + filter := bson.D{{"enrollment", bson.D{{"$gt", 20}}}} + opts := options.Find().SetLimit(2) + + cursor, err := coll.Find(context.TODO(), filter, opts) + + var results []Course + if err = cursor.All(context.TODO(), &results); err != nil { + panic(err) + } + for _, result := range results { + res, _ := bson.MarshalExtJSON(result, false, false) + fmt.Println(string(res)) + } + + .. output:: + :language: none + :visible: false + + {"title":"World Fiction","enrollment":35} + {"title":"Abstract Algebra","enrollment":60} + +Multiple Options +~~~~~~~~~~~~~~~~ + +The driver performs the limit behavior last regardless of the order in which you set +any other options. For example, the following option configurations produce the same +result, regardless of the order in which ``SetLimit()`` is called: + +.. code-block:: go + :copyable: false + + opts := options.Find().SetSort(bson.D{{"enrollment", -1}}).SetSkip(1).SetLimit(2) + opts := options.Find().SetLimit(2).SetSort(bson.D{{"enrollment", -1}}).SetSkip(1) + +The following example performs a ``Find()`` operation with the following behavior: + +- Sorts the results in descending order on the ``enrollment`` field +- Skips the first document +- Returns the first two of the remaining documents + +.. io-code-block:: + :copyable: true + + .. input:: + :language: go + + filter := bson.D{} + opts := options.Find().SetSort(bson.D{{"enrollment", -1}}).SetLimit(2).SetSkip(1) + + cursor, err := coll.Find(context.TODO(), filter, opts) + + var results []Course + if err = cursor.All(context.TODO(), &results); err != nil { + panic(err) + } + for _, result := range results { + res, _ := bson.MarshalExtJSON(result, false, false) + fmt.Println(string(res)) + } + + .. output:: + :language: none + :visible: false + + {"title":"Abstract Algebra","enrollment":60} + {"title":"Plate Tectonics","enrollment":35} + +.. _golang-limit-aggregation: + +Aggregation +~~~~~~~~~~~ + +You can also include the :manual:`$limit ` +stage to specify a limit in an aggregation pipeline. + +The following example shows how to return three documents: + +.. io-code-block:: + :copyable: true + + .. input:: + :language: go + + limitStage := bson.D{{"$limit", 3}} + + cursor, err := coll.Aggregate(context.TODO(), mongo.Pipeline{limitStage}) + if err != nil { + panic(err) + } + + var results []Course + if err = cursor.All(context.TODO(), &results); err != nil { + panic(err) + } + for _, result := range results { + res, _ := bson.MarshalExtJSON(result, false, false) + fmt.Println(string(res)) + } + + .. output:: + :language: none + :visible: false + + {"title":"World Fiction","enrollment":35} + {"title":"Abstract Algebra","enrollment":60} + {"title":"Modern Poetry","enrollment":12} + + +Additional Information +---------------------- + +To learn more about the operations discussed in this guide, see the following +documentation: + +- :ref:`golang-query-document` +- :ref:`golang-retrieve` +- :ref:`golang-compound-operations` +- :ref:`golang-aggregation` + +To learn about sorting text scores from your text search, see :ref:`golang-search-text`. + +API Documentation +~~~~~~~~~~~~~~~~~ + +To learn more about any of the methods or types discussed in this +guide, see the following API Documentation: + +- `Find() <{+api+}/mongo#Collection.Find>`__ +- `FindOptionsBuilder.SetSort() <{+api+}/mongo/options#FindOptionsBuilder.SetSort>`__ +- `Aggregate() <{+api+}/mongo#Collection.Aggregate>`__ +- `FindOne() <{+api+}/mongo#Collection.FindOne>`__ +- `FindOneAndDelete() <{+api+}/mongo#Collection.FindOneAndDelete>`__ +- `FindOneAndUpdate() <{+api+}/mongo#Collection.FindOneAndUpdate>`__ +- `FindOneAndReplace() <{+api+}/mongo#Collection.FindOneAndReplace>`__ +- `CountDocuments() <{+api+}/mongo#Collection.CountDocuments>`__ +- `GridFSBucket.Find() <{+api+}/mongo#GridFSBucket.Find>`__ diff --git a/source/fundamentals/crud/read-operations/text.txt b/source/crud/query/text.txt similarity index 99% rename from source/fundamentals/crud/read-operations/text.txt rename to source/crud/query/text.txt index 38505737..63c60027 100644 --- a/source/fundamentals/crud/read-operations/text.txt +++ b/source/crud/query/text.txt @@ -1,8 +1,8 @@ .. _golang-search-text: -=========== -Search Text -=========== +===================== +Perform a Text Search +===================== .. meta:: :description: Learn how to perform text searches with the MongoDB Go Driver, including creating text indexes and sorting results by relevance. diff --git a/source/fundamentals/transactions.txt b/source/crud/transactions.txt similarity index 100% rename from source/fundamentals/transactions.txt rename to source/crud/transactions.txt diff --git a/source/crud/update.txt b/source/crud/update.txt new file mode 100644 index 00000000..c3c8660c --- /dev/null +++ b/source/crud/update.txt @@ -0,0 +1,324 @@ +.. _golang-change-document: +.. _golang-update: +.. _golang-update-documents: + +================ +Update Documents +================ + +.. facet:: + :name: genre + :values: reference + +.. meta:: + :keywords: code example, write operation, change data + :description: Learn how to modify MongoDB documents using update and replace operations, including methods like updateOne(), updateMany(), and replaceOne(). + +.. contents:: On this page + :local: + :backlinks: none + :depth: 2 + :class: singlecol + +.. toctree:: + :caption: Update Documents + + Replace Documents + Update Arrays + Upsert + +Overview +-------- + +In this guide, you can learn how to update documents in MongoDB by using +**update** operations. + +Update operations change the fields that you specify while leaving other +fields and values unchanged. + +In MongoDB, all methods to modify documents follow the same pattern: + +.. figure:: /includes/figures/change_diagram.png + :alt: Change method signature + +.. note:: Placeholder + + ``changeX`` is a placeholder and not a real method. + +The pattern expects you to: + +* Specify a query filter to match one or more documents to modify. +* Specify the field and value changes. +* Specify options, if you must modify the method behavior. + +The driver provides the following methods to update documents: + +* ``UpdateByID()``: Updates a single document based on its ``_id``. +* ``UpdateOne()``: Updates a single document. +* ``UpdateMany()``: Updates multiple documents. + +A Note About _id +~~~~~~~~~~~~~~~~~ + +Each document in a MongoDB collection has a unique and immutable ``_id`` +field. You cannot use update operations to change the +``_id`` field. If you attempt to change this field, the update +methods return a ``WriteError``. + +.. _golang-update-document: + +Parameters +---------- + +Each method takes an **update document** that includes at least one **update operator**. +The update operator specifies the type of update to perform. The update +document also includes the fields and values that describe the change. +Update documents use the following format: + +.. code-block:: go + + bson.D{{"", bson.D{{"", }, + {"", }, ... }}, + {"", ... }, ... } + +See the MongoDB server manual for a :manual:`complete list of update operators +and descriptions `. + +.. tip:: + + ``UpdateOne()`` updates the first document that matches the query filter + you provide. To ensure that you update the correct document, you can use the ``sort`` + option to specify the order in which the operation finds documents. To learn more, + see the `UpdateOneOptions <{+api+}/mongo/options#UpdateOneOptions>`__ API documentation. + +.. note:: Aggregation Pipelines in Update Operations + + You can use aggregation pipelines made up of a subset of aggregation + stages in update operations. To learn more about + the aggregation stages MongoDB supports in + aggregation pipelines, see the tutorial on performing + :manual:`Updates with Aggregation Pipeline + ` + tutorial in the Server Manual. + +Return Values +------------- + +``UpdateOne()``, ``UpdateByID()``, and ``UpdateMany()`` return an +``UpdateResult`` type that contains information about the update +operation if the operation is successful. The ``UpdateResult`` type +contains the following properties: + +.. list-table:: + :widths: 30 70 + :header-rows: 1 + + * - Property + - Description + + * - ``MatchedCount`` + - The number of documents matched by the filter + + * - ``ModifiedCount`` + - The number of documents modified by the operation + + * - ``UpsertedCount`` + - The number of documents upserted by the operation + + * - ``UpsertedID`` + - The ``_id`` of the upserted document, or ``nil`` if there is none + +If multiple documents match the query filter passed to ``UpdateOne()``, +the method selects and updates the first matched document. If no +documents match the query filter, the update operation makes no +changes. + +See the :ref:`upsert guide ` +to learn how to insert a new document if no documents match the query filter. + +UpdateOne() Example +------------------- + +The following example uses the ``listingsAndReviews`` collection in the +``sample_airbnb`` dataset from the :atlas:`Atlas sample datasets `. +The following document describes an airbnb listing: + +.. code-block:: json + :copyable: false + + { + "_id": "10006546", + "listing_url": "https://www.airbnb.com/rooms/10006546", + "name": "Ribeira Charming Duplex", + "summary": "Fantastic duplex apartment with three bedrooms, located in the historic area of Porto, Ribeira (Cube)...", + ... + "minimum_nights": "2", + "maximum_nights": "30", + ... + "accommodates": 8, + ... + } + +The following example uses the ``UpdateOne()`` method to: + +- Match the document where the ``_id`` value is ``"10006546"``. +- Set the ``name`` field to ``"Ribiera River View Duplex"``. +- Increment the value of the ``accommodates`` field by ``1``. + +.. io-code-block:: + :copyable: true + + .. input:: + :language: go + + filter := bson.D{{"_id", "10006546"}} + update := bson.D{{"$set", bson.D{{"name", "Ribiera River View Duplex"}}}, + {"$inc", bson.D{{"accomodates", 1}}}} + + result, err := collection.UpdateOne(context.TODO(), filter, update) + fmt.Printf("Documents matched: %v\n", result.MatchedCount) + fmt.Printf("Documents updated: %v\n", result.ModifiedCount) + + .. output:: + :language: none + :visible: false + + Documents matched: 1 + Documents updated: 1 + +The following shows the updated document resulting from the preceding update operation: + +.. code-block:: json + :copyable: false + + { + "_id": "10006546", + "listing_url": "https://www.airbnb.com/rooms/10006546", + "name": "Ribeira River View Duplex", + "summary": "Fantastic duplex apartment with three bedrooms, located in the historic area of Porto, Ribeira (Cube)...", + ... + "minimum_nights": "2", + "maximum_nights": "30", + ... + "accommodates": 9, + ... + } + +UpdateOne() Example: Full File +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. include:: /includes/usage-examples/example-intro.rst + +The following example is a fully runnable file that finds and updates an +existing document in the ``restaurants`` collection. Select the +:guilabel:`Struct` or :guilabel:`bson.D` tab to see the corresponding code: + +.. tabs:: + + .. tab:: Struct + :tabid: structExample + + The following code uses a struct to define the filter and update a document in the ``restuarants`` collection: + + .. io-code-block:: + :copyable: true + + .. input:: /includes/usage-examples/code-snippets/updateOne.go + :language: go + :dedent: + + .. output:: + :language: none + :visible: false + + Documents updated: 1 + + .. tab:: bson.D + :tabid: bsonDExample + + The following code uses a ``bson.D`` type to define the filter and update a document in the ``restuarants`` collection: + + .. io-code-block:: + :copyable: true + + .. input:: /includes/usage-examples/code-snippets/updateOneBson.go + :language: go + :dedent: + + .. output:: + :language: none + :visible: false + + Documents updated: 1 + +UpdateMany() Example: Full File +------------------------------- + +.. include:: /includes/usage-examples/example-intro.rst + +The following example is a fully runnable file that finds and updates multiple +existing documents in the ``restaurants`` collection. Select the +:guilabel:`Struct` or :guilabel:`bson.D` tab to see the corresponding code: + +.. tabs:: + + .. tab:: Struct + :tabid: structExample + + The following code uses a struct to define the filter and update multiple documents in the ``restuarants`` collection: + + .. io-code-block:: + :copyable: true + + .. input:: /includes/usage-examples/code-snippets/updateMany.go + :language: go + :dedent: + + .. output:: + :language: none + :visible: false + + Documents updated: 296 + + .. tab:: bson.D + :tabid: bsonDExample + + The following code uses a ``bson.D`` type to define the filter and update multiple documents in the ``restuarants`` collection: + + .. io-code-block:: + :copyable: true + + .. input:: /includes/usage-examples/code-snippets/updateManyBson.go + :language: go + :dedent: + + .. output:: + :language: none + :visible: false + + Documents updated: 296 + +Additional Information +---------------------- + +To learn more about the operations mentioned, see the following +guides: + +- :ref:`golang-query-document` +- :ref:`golang-retrieve` +- :ref:`golang-compound-operations` +- :manual:`Update Operators ` + +To learn more about updating array elements, see :ref:`golang-update-arrays`. + +API Documentation +~~~~~~~~~~~~~~~~~ + +To learn more about any of the methods or types discussed in this +guide, see the following API Documentation: + +- `WriteError <{+api+}/mongo#WriteError>`__ +- `UpdateOne() <{+api+}/mongo#Collection.UpdateOne>`__ +- `UpdateByID() <{+api+}/mongo#Collection.UpdateByID>`__ +- `UpdateMany() <{+api+}/mongo#Collection.UpdateMany>`__ +- `UpdateResult <{+api+}/mongo#UpdateResult>`__ diff --git a/source/fundamentals/crud/write-operations/embedded-arrays.txt b/source/crud/update/embedded-arrays.txt similarity index 100% rename from source/fundamentals/crud/write-operations/embedded-arrays.txt rename to source/crud/update/embedded-arrays.txt diff --git a/source/crud/update/replace.txt b/source/crud/update/replace.txt new file mode 100644 index 00000000..3b65a7a3 --- /dev/null +++ b/source/crud/update/replace.txt @@ -0,0 +1,130 @@ +.. _golang-replacement-document: +.. _golang-replace: + +================= +Replace Documents +================= + +.. contents:: On this page + :local: + :backlinks: none + :depth: 2 + :class: singlecol + +.. facet:: + :name: genre + :values: reference + +.. meta:: + :keywords: code example, go, write, add data, change + +Overview +-------- + +In this guide, you can learn how to use the {+driver-short+} to perform a replace +operation on a document in a MongoDB collection. A replace operation performs +differently than an update operation. An update operation +modifies only the specified fields in a target document. A replace operation removes +all fields in the target document and replaces them with new ones. + +Parameters +---------- + +``ReplaceOne()`` expects a **replacement document**, which is the document +that you want to take the place of an existing document. Replacement +documents use the following format: + +.. code-block:: go + + bson.D{{"", ""}, {"", ""}, ... } + +Return Values +------------- + +``ReplaceOne()`` returns an ``UpdateResult`` type that +contains information about the replace operation if the operation is +successful. The ``UpdateResult`` type contains the following properties: + +.. list-table:: + :widths: 30 70 + :header-rows: 1 + + * - Property + - Description + + * - ``MatchedCount`` + - The number of documents matched by the filter + + * - ``ModifiedCount`` + - The number of documents modified by the operation + + * - ``UpsertedCount`` + - The number of documents upserted by the operation + + * - ``UpsertedID`` + - The ``_id`` of the upserted document, or ``nil`` if there is none + +If multiple documents match the query filter passed to ``ReplaceOne()``, +the method selects and replaces the first matched document. Your replace +operation fails if no documents match the query filter. + +Example +------- + +The following document describes a kitchen item: + +.. code-block:: json + :copyable: false + + { + "_id" : 2056, + "item" : "Mug", + "brand" : "Simply Ceramics", + "price" : 2.99, + "material" : "Glass" + } + +The following example uses the ``ReplaceOne()`` method to substitute +this document with one that contains an ``item`` field with a +value of "Cup" and a ``quantity`` field with a value of 107: + +.. io-code-block:: + :copyable: true + + .. input:: + :language: go + + filter := bson.D{{"_id", 2056}} + replacement := bson.D{{"item", "Cup"}, {"quantity", 107}} + + result, err := collection.ReplaceOne(context.TODO(), filter, replacement) + fmt.Printf("Documents matched: %v\n", result.MatchedCount) + fmt.Printf("Documents replaced: %v\n", result.ModifiedCount) + + .. output:: + :language: none + :visible: false + + Documents matched: 1 + Documents replaced: 1 + +The replaced document contains the contents of the replacement document +and the immutable ``_id`` field as follows: + +.. code-block:: json + :copyable: false + + { + "_id" : 2056, + "item" : "Cup", + "quantity" : 107 + } + +API Documentation +----------------- + +To learn more about any of the methods or types discussed in this +guide, see the following API Documentation: + +- `ReplaceOne() <{+api+}/mongo#Collection.ReplaceOne>`__ +- `UpdateResult <{+api+}/mongo#UpdateResult>`__ diff --git a/source/fundamentals/crud/write-operations/upsert.txt b/source/crud/update/upsert.txt similarity index 99% rename from source/fundamentals/crud/write-operations/upsert.txt rename to source/crud/update/upsert.txt index f9dc2949..2b58049c 100644 --- a/source/fundamentals/crud/write-operations/upsert.txt +++ b/source/crud/update/upsert.txt @@ -85,7 +85,7 @@ method in the options of the following write operation methods: equivalent to passing ``false`` to the ``SetUpsert()`` method. Example -~~~~~~~ +------- The following example performs the following actions: diff --git a/source/data-formats.txt b/source/data-formats.txt new file mode 100644 index 00000000..d6194b89 --- /dev/null +++ b/source/data-formats.txt @@ -0,0 +1,42 @@ +.. This page is hidden from the TOC and search indexing. + +.. meta:: + :robots: noindex, nosnippet + +.. _golang-data-formats: + +======================== +Specialized Data Formats +======================== + +.. contents:: On this page + :local: + :backlinks: none + :depth: 2 + :class: singlecol + +.. facet:: + :name: genre + :values: reference + +.. meta:: + :keywords: bson, JSON, date, time, marshal, unmarshal, serialization + +.. toctree:: + :titlesonly: + :maxdepth: 1 + + Use Struct Tags + BSON + Extended JSON + +Overview +-------- + +You can use several types of specialized data formats in the +{+driver-short+}. To learn how to work with these data formats, see the +following guides: + +- Learn how to work with BSON documents in the :ref:`golang-bson` guide. +- Learn how to convert between {+language+} types and Extended JSON in the + :ref:`golang-extended-json` guide. diff --git a/source/fundamentals/bson.txt b/source/data-formats/bson.txt similarity index 100% rename from source/fundamentals/bson.txt rename to source/data-formats/bson.txt diff --git a/source/data-formats/extended-json.txt b/source/data-formats/extended-json.txt new file mode 100644 index 00000000..fe159e23 --- /dev/null +++ b/source/data-formats/extended-json.txt @@ -0,0 +1,260 @@ +.. _golang-extended-json: + +=================================== +Document Data Format: Extended JSON +=================================== + +.. contents:: On this page + :local: + :backlinks: none + :depth: 2 + :class: singlecol + +.. facet:: + :name: genre + :values: reference + +.. meta:: + :keywords: code example, bson, relaxed, canonical, legacy + +Overview +-------- + +JSON is a data format that represents the values of objects, arrays, numbers, +strings, booleans, and nulls. The **Extended JSON** format defines a reserved +set of keys prefixed with the ``$`` character to represent field type +information that directly corresponds to each type in BSON, the format +that MongoDB uses to store data. + +Extended JSON Formats +--------------------- + +MongoDB Extended JSON features different string formats to represent +BSON data. Each of the formats conforms to the `JSON RFC +`__ and meets specific +use cases. + +The **Extended** format, also known as the **Canonical** +format, features specific representations for every BSON type for +bidirectional conversion without loss of information. The **Relaxed** +format is more concise and closer to ordinary JSON, but does not +represent all the type information such as the specific byte size of +number fields. + +The following table provides descriptions of the JSON formats: + +.. list-table:: + :header-rows: 1 + :stub-columns: 1 + :widths: 10 40 + + * - Name + - Description + + * - **Extended** + - | Also known as the *canonical* format, this JSON representation avoids loss of + BSON type information. + | This format prioritizes type preservation at the loss of human-readability and + interoperability with older formats. + + * - **Relaxed Mode** + - | JSON representation that describes BSON documents with some type information loss. + | This format prioritizes human-readability and interoperability at the loss of + certain type information. + + * - **Shell** + - | JSON representation that matches the syntax used in the MongoDB shell. + | This format prioritizes compatibility with the MongoDB shell, which often uses + JavaScript functions to represent types. + + * - **Strict** + - | *Deprecated* This representation is the legacy format that fully conforms to + the JSON RFC and allows any JSON parser to read the type information. + +To learn more about JSON, BSON, and Extended JSON, see our +:website:`article about JSON and BSON ` +and the :manual:`Extended JSON ` +reference in the {+mdb-server+} manual. + +.. _golang-extended_json_examples: + +Extended JSON Examples +~~~~~~~~~~~~~~~~~~~~~~ + +The following tabs show a document containing an ObjectId, date, and long +number field represented in each Extended JSON format. Select from the +tabs to see the same data presented in each JSON format: + +.. tabs:: + + .. tab:: Extended + :tabid: extended-format + + .. code-block:: json + + { + "_id": { "$oid": "573a1391f29313caabcd9637" }, + "createdAt": { "$date": { "$numberLong": "1601499609" }}, + "numViews": { "$numberLong": "36520312" } + } + + .. tab:: Relaxed Mode + :tabid: relaxed-mode-format + + .. code-block:: json + + { + "_id": { "$oid": "573a1391f29313caabcd9637" }, + "createdAt": { "$date": "2020-09-30T18:22:51.648Z" }, + "numViews": 36520312 + } + + .. tab:: Shell + :tabid: shell-format + + .. code-block:: json + + { + "_id": ObjectId("573a1391f29313caabcd9637"), + "createdAt": ISODate("2020-09-30T18:22:51.648Z"), + "numViews": NumberLong("36520312") + } + + .. tab:: Strict + :tabid: strict-format + + .. code-block:: json + + { + "_id": { "$oid": "573a1391f29313caabcd9637" }, + "createdAt": { "$date": 1601499609 }, + "numViews": { "$numberLong": "36520312" } + } + +Read Extended JSON +------------------ + +You can read an Extended JSON string into a {+language+} struct by +calling the ``bson.UnmarshalExtJSON()`` method. This method parses an +Extended JSON string and stores the result in the specified value parameter. + +This example shows how you can read an Extended JSON string +into the following ``Person`` struct: + +.. literalinclude:: /includes/data-formats/ejson.go + :start-after: begin-person-struct + :end-before: end-person-struct + :language: go + :dedent: + +The following code uses the ``UnmarshalExtJSON()`` method to read an +Extended JSON string and unmarshal the data into an instance of ``Person``: + +.. io-code-block:: + :copyable: true + + .. input:: /includes/data-formats/ejson.go + :start-after: begin-unmarshal + :end-before: end-unmarshal + :language: go + :emphasize-lines: 4 + :dedent: + + .. output:: + :language: none + :visible: false + + Go Struct Representation: + {ID:ObjectID("578f6fa2df35c7fbdbaed8c5") Name:Liana Ruiz Age:46 Birthday:569203200000 Address:{Street:500 Slippery Rock Road City:Round Rock State:AR} Hobbies:[cycling baking]} + +Write Extended JSON +------------------- + +You can produce an Extended JSON string from an instance of a +{+language+} struct by calling the ``bson.MarshalExtJSON()`` method. +The following example creates an Extended JSON string in the Relaxed +format from an instance of ``Person``: + +.. io-code-block:: + :copyable: true + + .. input:: /includes/data-formats/ejson.go + :start-after: begin-marshal + :end-before: end-marshal + :language: go + :emphasize-lines: 10 + :dedent: + + .. output:: + :language: none + :visible: false + + Extended JSON Representation: + {"_id":{"$oid":"686688fa7c1a2e75405f4697"},"name":"Matteo Carisi","age":49,"birthday":{"$date":"1975-10-30T00:00:00Z"},"address":{"street":"14a Corner Court","city":"Springfield","state":"IL"},"hobbies":["cooking","birdwatching"]} + +The second parameter to ``MarshalExtJSON()`` determines if the output +string is in Canonical (Extended) format or Relaxed format. The +preceding example passes ``false`` as the ``canonical`` parameter, so +the output is Relaxed JSON. + +.. note:: Dates Before Epoch Time + + When you marshal a date value that is before January 1, 1970, + 00:00:00 UTC (Epoch time), it appears as a Unix timestamp in Relaxed + JSON. If the date is after the Epoch time, it appears in a readable + date format. + +Format Extended JSON +~~~~~~~~~~~~~~~~~~~~ + +You can use the ``bson.MarshalExtJSONIndent()`` method to print a +formatted Extended JSON string that includes newlines, prefixes, and +indentation. + +The following code uses the ``MarshalExtJSONIndent()`` method to print +the JSON string from the preceding example formatted with two spaces of +indentation: + +.. io-code-block:: + :copyable: true + + .. input:: /includes/data-formats/ejson.go + :start-after: begin-marshal-fmt + :end-before: end-marshal-fmt + :language: go + :emphasize-lines: 10 + :dedent: + + .. output:: + :language: none + :visible: false + + { + "_id": { + "$oid": "686688fa7c1a2e75405f4697" + }, + "name": "Matteo Carisi", + "age": 49, + "birthday": { + "$date": "1975-10-30T00:00:00Z" + }, + "address": { + "street": "14a Corner Court", + "city": "Springfield", + "state": "IL" + }, + "hobbies": [ + "cooking", + "birdwatching" + ] + } + +API Documentation +----------------- + +To learn more about the methods and types used in this guide, see the +following API documentation: + +- `UnmarshalExtJSON() <{+api+}/bson#UnmarshalExtJSON>`__ +- `MarshalExtJSON() <{+api+}/bson#MarshalExtJSON>`__ +- `MarshalExtJSONIndent() <{+api+}/bson#MarshalExtJSONIndent>`__ diff --git a/source/data-formats/struct-tagging.txt b/source/data-formats/struct-tagging.txt new file mode 100644 index 00000000..99b08837 --- /dev/null +++ b/source/data-formats/struct-tagging.txt @@ -0,0 +1,72 @@ +.. _golang-struct-tags-usage-example: + +=============== +Use Struct Tags +=============== + +.. meta:: + :description: Learn how to use struct tags in Go to control BSON field names when inserting documents with the MongoDB Go Driver. + +You can specify the way that the Go Driver converts Go +structs to :manual:`BSON ` by using struct tags. + +Example +------- +.. TODO: Add the Usage Examples intro include once it is merged + +The following code declares a struct of type ``BlogPost``. This struct +contains a struct tag that maps the ``WordCount`` field to the BSON +field name ``word_count``. By default, the driver marshals the other +fields as the lowercase of the struct field name: + +.. literalinclude:: /includes/usage-examples/code-snippets/struct-tag.go + :start-after: begin struct + :end-before: end struct + :language: go + :dedent: + +The following example creates a ``BlogPost`` instance and inserts it +into the ``posts`` collection. During the insert operation, the driver +interprets the struct tag to marshal the ``WordCount`` +struct field as ``word_count``: + +.. literalinclude:: /includes/usage-examples/code-snippets/struct-tag.go + :start-after: begin create and insert + :end-before: end create and insert + :language: go + :dedent: + +View a `fully runnable example. <{+example+}/struct-tag.go>`__ + +Expected Result +--------------- + +After you run the full example, you can find the following document +in the ``posts`` collection: + +.. code-block:: json + :copyable: false + + { + "_id" : ObjectId("..."), + "title" : "Annuals vs. Perennials?", + "author" : "Sam Lee", + "word_count" : 682, + "lastupdated": ..., + "tags" : ["seasons", "gardening", "flower"] + } + +For an example on how to find a document, see the :ref:`golang-find-one` guide. + +Additional Information +---------------------- + +To learn more about using struct tags, converting to/from BSON, and +handling potential errors, see the :ref:`Work with BSON ` guide. + +API Documentation +~~~~~~~~~~~~~~~~~ + +- `Structs and Struct Tags <{+api+}@{+full-version+}/bson#hdr-Structs>`__ +- `InsertOne() <{+api+}/mongo#Collection.InsertOne>`__ +- `FindOne() <{+api+}/mongo#Collection.FindOne>`__ diff --git a/source/databases-collections.txt b/source/databases-collections.txt new file mode 100644 index 00000000..8a2b26a9 --- /dev/null +++ b/source/databases-collections.txt @@ -0,0 +1,145 @@ +.. _golang-databases-collections: + +========================= +Databases and Collections +========================= + + +.. contents:: On this page + :local: + :backlinks: none + :depth: 2 + :class: singlecol + +.. facet:: + :name: genre + :values: reference + +.. meta:: + :keywords: table, row, organize, storage, code example + :description: Learn how to manage MongoDB databases and collections using the Go driver, including accessing, creating, and deleting collections. + +Overview +-------- + +In this guide, you can learn how to interact with MongoDB databases and +collections by using the {+driver-short+}. + +MongoDB organizes data into a hierarchy of the following levels: + +- **Databases**: Top-level data structures in a MongoDB deployment that store + collections. +- **Collections**: Groups of MongoDB documents. They are analogous to tables in + relational databases. +- **Documents**: Units that store literal data such as strings, numbers, dates, + and other embedded documents. For more information about document field types + and structure, see the :manual:`Documents ` entry in the + {+mdb-server+} manual. + +Access a Database +----------------- + +You can access a database by using the ``Database()`` method on a ``Client`` +instance. + +The following example accesses a database named ``test_database``: + +.. literalinclude:: /includes/databases-collections.go + :start-after: start-access-database + :end-before: end-access-database + :language: go + :copyable: + :dedent: + +Access a Collection +------------------- + +You can access a collection by using the ``Collection()`` method on a +``Database`` instance. + +The following example accesses a collection named ``test_collection``: + +.. literalinclude:: /includes/databases-collections.go + :start-after: start-access-collection + :end-before: end-access-collection + :language: go + :copyable: + :dedent: + +.. tip:: + + If the provided collection name does not already exist in the database, + MongoDB implicitly creates the collection when you first insert data into it. + +Create a Collection +------------------- + +To explicity create a collection, you can use the ``CreateCollection()`` method +on a ``Database`` instance. + +The following example creates a collection named ``example_collection``: + +.. literalinclude:: /includes/databases-collections.go + :start-after: start-create-collection + :end-before: end-create-collection + :language: go + :copyable: + :dedent: + +You can specify collection options, such as maximum size and document validation +rules, by passing an ``options.CreateCollectionOptions`` struct to the +``CreateCollection()`` method of a ``Database`` instance. For a full list of +optional parameters, see the :manual:`create command +` entry in the {+mdb-server+} manual. + +Get a List of Collections +------------------------- + +You can query for a list of collections in a database by using the +``ListCollections()`` method on a ``Database`` instance. + +The following example gets a list of all the collections in a database, and then +prints the collection names to the console: + +.. literalinclude:: /includes/databases-collections.go + :start-after: start-list-collections + :end-before: end-list-collections + :language: go + :copyable: + :dedent: + +Delete a Collection +------------------- + +You can delete a collection by using the ``Drop()`` method on a ``Database`` +instance. + +The following example deletes a collection named +``test_collection``: + +.. literalinclude:: /includes/databases-collections.go + :start-after: start-delete-collection + :end-before: end-delete-collection + :language: go + :copyable: + :dedent: + +.. warning:: Dropping a Collection Deletes All Data in the Collection + + Dropping a collection from your database permanently deletes all documents + and all indexes within that collection. + + Drop a collection only if you no longer need the data in that collection. + +API Documentation +----------------- + +To learn more about any of the types or methods discussed in this guide, see the +following API documentation: + +- `Client <{+api+}/mongo#Client>`__ +- `Database <{+api+}/mongo#Database>`__ +- `Collection <{+api+}/mongo#Collection>`__ +- `CreateCollection() <{+api+}/mongo#Database.CreateCollection>`__ +- `ListCollections() <{+api+}/mongo#Database.ListCollections>`__ +- `Drop() <{+api+}/mongo#Database.Drop>`__ \ No newline at end of file diff --git a/source/fundamentals/connections.txt b/source/fundamentals/connections.txt deleted file mode 100644 index 7bb9145e..00000000 --- a/source/fundamentals/connections.txt +++ /dev/null @@ -1,39 +0,0 @@ -.. _golang-connection: - -=========== -Connections -=========== - -.. meta:: - :description: Explore how to configure connections to a MongoDB deployment using the MongoDB Go Driver, including options for TLS and network compression. - -.. toctree:: - - Connection Guide - Connection Options - Network Compression - Configure TLS - Connect with AWS Lambda - -.. contents:: On this page - :local: - :backlinks: none - :depth: 1 - :class: singlecol - -Overview --------- - -Learn how to use the {+driver-short+} to configure your application's -connection to a MongoDB deployment in the following sections: - -- :ref:`golang-connection-guide` -- :ref:`golang-connection-options` -- :ref:`golang-network-compression` -- :ref:`golang-tls` -- :atlas:`Connect to MongoDB Atlas from AWS Lambda ` - -To learn how to authenticate to MongoDB, see the following pages: - -- :ref:`golang-authentication-mechanisms` -- :ref:`golang-enterprise-authentication-mechanisms` diff --git a/source/fundamentals/connections/connection-guide.txt b/source/fundamentals/connections/connection-guide.txt deleted file mode 100644 index fa9089f3..00000000 --- a/source/fundamentals/connections/connection-guide.txt +++ /dev/null @@ -1,187 +0,0 @@ -.. _golang-connection-guide: - -================ -Connection Guide -================ - -.. facet:: - :name: genre - :values: tutorial - -.. meta:: - :description: Learn how to use the MongoDB Go Driver to connect to MongoDB. - :keywords: connection string, client options, replica set - -.. contents:: On this page - :local: - :backlinks: none - :depth: 2 - :class: singlecol - -Overview --------- - -In this guide, you can learn how to connect to a MongoDB instance or -replica set deployment by using the {+driver-short+}. - -You can use the {+driver-short+} to connect to deployments hosted in the -following environments: - -.. include:: /includes/fact-environments.rst - -.. _golang-connection-uri: - --------------- -Connection URI --------------- - -A **connection URI**, also known as a connection string, tells the -driver how to connect to MongoDB and how to behave while connected. - -Parts of a Connection URI -~~~~~~~~~~~~~~~~~~~~~~~~~ - -The following example explains each part of a sample connection URI: - -.. figure:: /includes/figures/connection_uri_parts.png - :alt: Each part of the connection string - -In this example, we use ``mongodb`` for the protocol, which specifies the -:manual:`Standard Connection String Format -`. -You can also use the :manual:`DNS Seed List Connection Format -` if you -want more flexibility of deployment and the ability to change the -servers in rotation without reconfiguring clients. - -The next part of the connection string contains your database username and, if -you are using password-based authentication, your password. Replace the value of -``user`` with your database username and ``pass`` with your password. If you are using an -authentication mechanism that does not require a username and password, omit -this part of the connection URI. - -The next part of the connection string specifies the hostname or IP address and -port of your MongoDB instance. In the preceding example, we use ``sample.host`` -as the hostname and ``27017`` as the port. Replace these values to point to -your MongoDB instance. - -The last part of the connection string specifies connection and authentication -options. In the example, we set two connection options: -``maxPoolSize=20`` and ``w=majority``. To learn more about connection -options, see the :ref:`golang-connection-options` guide. - -Connection Example -~~~~~~~~~~~~~~~~~~ - -To connect to MongoDB, you must create a client. A client manages your -connections and runs database commands. - -.. tip:: Reuse Your Client - - We recommend that you reuse your client across sessions and operations. - You can use the same ``Client`` instance to perform multiple tasks, instead of - creating a new one each time. The ``Client`` type is safe for - concurrent use by multiple `goroutines - `__. To learn more about - how connection pools work in the driver, see the :ref:`FAQ page `. - -You can create a client that uses your connection string and other -client options by passing a ``ClientOptions`` object to the ``Connect()`` -method. - -To specify your connection URI, pass it to the ``ApplyURI()`` -method, which returns a new ``ClientOptions`` instance. To set any other -options, call the relevant helper method from the ``options`` package. - -To learn more about connection options, see the -:ref:`Connection Options section `. To learn -more about creating a client, see the API documentation for `Client -<{+api+}/mongo#Client>`__ and `Connect() <{+api+}/mongo#Connect>`__. - -You can set the {+stable-api+} version as an option to avoid -breaking changes when you upgrade to a new server version. To -learn more about the {+stable-api+} feature, see the :ref:`{+stable-api+} page -`. - -The following code shows how you can create a client that uses an Atlas -connection string and the {+stable-api+} version, connect to MongoDB, and -verify that the connection is successful: - -.. _go-connection-example-code: - -.. literalinclude:: /includes/fundamentals/code-snippets/srv.go - :language: go - -.. tip:: - - Follow the :ref:`Quick Start guide ` - to retrieve your Atlas connection string. - -.. note:: - - To learn about connecting to Atlas Serverless, see the - :ref:`Serverless Instance Limitations page - ` to identify the minimum driver version - required. - --------------------------------- -Other Ways to Connect to MongoDB --------------------------------- - -If you are connecting to a single MongoDB server instance or replica set -that is not hosted on Atlas, see the following sections to find out how to -connect. - -Connect to a MongoDB Server on Your Local Machine -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -.. include:: /includes/localhost-connection.rst - -To test whether you can connect to your server, replace the connection -string with your localhost connection string in the preceding code example. - -Connect to a Replica Set -~~~~~~~~~~~~~~~~~~~~~~~~ - -A MongoDB replica set deployment is a group of connected instances that -store the same set of data. This configuration provides data -redundancy and high data availability. - -To connect to a replica set deployment, specify the hostname and port numbers -of each instance, separated by commas, and the replica set name as the value -of the ``replicaSet`` parameter in the connection string. In the following -example, the hostnames are ``host1``, ``host2``, and ``host3``, and the -port numbers are all ``27017``. The replica set name is ``myRS``. - -.. code-block:: none - - mongodb://host1:27017,host2:27017,host3:27017/?replicaSet=myRS - -When connecting to a replica set, the driver takes the following actions by default: - -- Discovers all replica set members when given the address of any one member. -- Dispatches operations to the appropriate member, such as instructions - to write against the **primary**. - -.. tip:: - - You can specify just one host to connect to a replica set. - However, to ensure connectivity when the specified host - is unavailable, you should provide the full list of hosts. - -Direct Connection -````````````````` - -To force operations on the host designated in the connection URI, -specify the ``directConnection`` option. Direct connections exhibit the -following behavior: - -- They don't support SRV strings. -- They fail on writes when the specified host is not the **primary**. -- They require you to specify a :manual:`secondary read preference - ` when the - specified host isn't the **primary** node. - -.. note:: Replica Set in Docker - - .. sharedinclude:: dbx/docker-replica-set.rst diff --git a/source/fundamentals/crud.txt b/source/fundamentals/crud.txt deleted file mode 100644 index 3fcff3c9..00000000 --- a/source/fundamentals/crud.txt +++ /dev/null @@ -1,29 +0,0 @@ -.. _golang-crud: - -=============== -CRUD Operations -=============== - -.. meta:: - :description: Explore how to perform CRUD operations using the MongoDB Go Driver, including creating, reading, updating, and deleting documents. - -.. toctree:: - :caption: CRUD Operations - - Read - Write - Compound Operations - Modify CRUD Execution - -CRUD (Create, Read, Update, Delete) operations enable you to work with -data stored in MongoDB. - -- :ref:`golang-crud-read-operations` find and return - documents stored in your database. -- :ref:`golang-crud-write-operations` insert, modify, - or delete documents in your database. - -Some operations combine aspects of read and write operations. To learn -more about these hybrid methods, see :ref:`golang-compound-operations`. - -To learn about how to modify the way your CRUD operations execute, see :ref:`golang-write-read-pref`. \ No newline at end of file diff --git a/source/fundamentals/crud/write-operations/modify.txt b/source/fundamentals/crud/write-operations/modify.txt deleted file mode 100644 index 6f021206..00000000 --- a/source/fundamentals/crud/write-operations/modify.txt +++ /dev/null @@ -1,335 +0,0 @@ -.. _golang-change-document: - -================ -Modify Documents -================ - -.. facet:: - :name: genre - :values: reference - -.. meta:: - :keywords: code example, write operation, change data - :description: Learn how to modify MongoDB documents using update and replace operations, including methods like updateOne(), updateMany(), and replaceOne(). - -.. contents:: On this page - :local: - :backlinks: none - :depth: 2 - :class: singlecol - -Overview --------- - -In this guide, you can learn how to modify documents in MongoDB using -**update** and **replace** operations. - -Update operations change the fields that you specify while leaving other -fields and values unchanged. Replace operations remove all existing fields -except for ``_id`` in a document and substitute the deleted fields with -the new fields and values you specify. - -In MongoDB, all methods to modify documents follow the same pattern: - -.. figure:: /includes/figures/change_diagram.png - :alt: Change method signature - -.. note:: Placeholder - - ``changeX`` is a placeholder and not a real method. - -The pattern expects you to: - -* Specify a query filter to match one or more documents to modify. -* Specify the field and value changes. -* Specify options, if you must modify the method behavior. - -The driver provides the following methods to modify documents: - -* ``UpdateByID()`` -* ``UpdateOne()`` -* ``UpdateMany()`` -* ``ReplaceOne()`` -* ``BulkWrite()`` *(not discussed in this guide)* -* ``FindOneAndUpdate()`` *(not discussed in this guide)* -* ``FindOneAndReplace()`` *(not discussed in this guide)* - -A Note About ``_id`` -~~~~~~~~~~~~~~~~~~~~ - -Each document in a MongoDB collection has a unique and immutable ``_id`` -field. You cannot use update and replace operations to change the -``_id`` field. If you attempt to change this field, the update and -replace methods return a ``WriteError``. - -.. _golang-update-documents: - -Update ------- - -Use the ``UpdateOne()`` or ``UpdateByID()`` method to update a single -document. - -Use the ``UpdateMany()`` method to update multiple documents. - -.. _golang-update-document: - -Parameters -~~~~~~~~~~ - -Each method takes an **update document** that includes at least one **update operator**. -The update operator specifies the type of update to perform. The update -document also includes the fields and values that describe the change. -Update documents use the following format: - -.. code-block:: go - - bson.D{{"", bson.D{{"", }, - {"", }, ... }}, - {"", ... }, ... } - -See the MongoDB server manual for a :manual:`complete list of update operators -and descriptions `. - -.. tip:: - - ``UpdateOne()`` updates the first document that matches the query filter - you provide. To ensure that you update the correct document, you can use the ``sort`` - option to specify the order in which the operation finds documents. To learn more, - see the `UpdateOneOptions <{+api+}/mongo/options#UpdateOneOptions>`__ API documentation. - -.. note:: Aggregation Pipelines in Update Operations - - If you are using MongoDB Server version 4.2 or later, you can use aggregation - pipelines made up of a subset of aggregation stages in update operations. To learn more about - the aggregation stages MongoDB supports in - aggregation pipelines, see our tutorial on performing - :manual:`updates with aggregation pipelines - `. - -Return Values -~~~~~~~~~~~~~ - -``UpdateOne()``, ``UpdateByID()``, and ``UpdateMany()`` return an -``UpdateResult`` type that contains information about the update -operation if the operation is successful. The ``UpdateResult`` type -contains the following properties: - -.. list-table:: - :widths: 30 70 - :header-rows: 1 - - * - Property - - Description - - * - ``MatchedCount`` - - The number of documents matched by the filter - - * - ``ModifiedCount`` - - The number of documents modified by the operation - - * - ``UpsertedCount`` - - The number of documents upserted by the operation - - * - ``UpsertedID`` - - The ``_id`` of the upserted document, or ``nil`` if there is none - -If multiple documents match the query filter passed to ``UpdateOne()``, -the method selects and updates the first matched document. If no -documents match the query filter, the update operation makes no -changes. - -See our :ref:`upsert guide ` -to learn how to insert a new document if no documents match the query filter. - -Example -``````` - -The following document describes an employee: - -.. code-block:: json - :copyable: false - - { - "_id" : 2158, - "name" : "Mary Shelley", - "department" : "Marketing", - "role" : "Marketing Analyst", - "bonus" : 2500, - ... - } - -The following example uses the ``UpdateByID()`` method to: - -- Match the document where the ``_id`` value is 2158. -- Set the ``name`` field to "Mary Wollstonecraft Shelley" and the - ``role`` field to "Marketing Director". -- Increment the value of the ``bonus`` field by 2000. - -.. io-code-block:: - :copyable: true - - .. input:: - :language: go - - filter := bson.D{{"_id", 2158}} - update := bson.D{{"$set", bson.D{{"name", "Mary Wollstonecraft Shelley"}, - {"role", "Marketing Director"}}}, {"$inc", bson.D{{"bonus", 2000}}}} - - result, err := collection.UpdateOne(context.TODO(), filter, update) - fmt.Printf("Documents matched: %v\n", result.MatchedCount) - fmt.Printf("Documents updated: %v\n", result.ModifiedCount) - - .. output:: - :language: none - :visible: false - - Documents matched: 1 - Documents updated: 1 - -The following shows the updated document resulting from the preceding update operation: - -.. code-block:: json - :copyable: false - - { - "_id" : 2158, - "name" : "Mary Wollstonecraft Shelley", - "department" : "Marketing", - "role" : "Marketing Director", - "bonus" : 4500, - ... - } - -.. _golang-replacement-document: - -Replace -------- - -Use the ``ReplaceOne()`` method to replace a single document. - -Parameters -~~~~~~~~~~ - -``ReplaceOne()`` expects a **replacement document**, which is the document -that you want to take the place of an existing document. Replacement -documents use the following format: - -.. code-block:: go - - bson.D{{"", ""}, {"", ""}, ... } - -Return Values -~~~~~~~~~~~~~ - -``ReplaceOne()`` returns an ``UpdateResult`` type that -contains information about the replace operation if the operation is -successful. The ``UpdateResult`` type contains the following properties: - -.. list-table:: - :widths: 30 70 - :header-rows: 1 - - * - Property - - Description - - * - ``MatchedCount`` - - The number of documents matched by the filter - - * - ``ModifiedCount`` - - The number of documents modified by the operation - - * - ``UpsertedCount`` - - The number of documents upserted by the operation - - * - ``UpsertedID`` - - The ``_id`` of the upserted document, or ``nil`` if there is none - -If multiple documents match the query filter passed to ``ReplaceOne()``, -the method selects and replaces the first matched document. Your replace -operation fails if no documents match the query filter. - -Example -``````` - -The following document describes a kitchen item: - -.. code-block:: json - :copyable: false - - { - "_id" : 2056, - "item" : "Mug", - "brand" : "Simply Ceramics", - "price" : 2.99, - "material" : "Glass" - } - -The following example uses the ``ReplaceOne()`` method to substitute -this document with one that contains an ``item`` field with a -value of "Cup" and a ``quantity`` field with a value of 107: - -.. io-code-block:: - :copyable: true - - .. input:: - :language: go - - filter := bson.D{{"_id", 2056}} - replacement := bson.D{{"item", "Cup"}, {"quantity", 107}} - - result, err := collection.ReplaceOne(context.TODO(), filter, replacement) - fmt.Printf("Documents matched: %v\n", result.MatchedCount) - fmt.Printf("Documents replaced: %v\n", result.ModifiedCount) - - .. output:: - :language: none - :visible: false - - Documents matched: 1 - Documents replaced: 1 - -The replaced document contains the contents of the replacement document -and the immutable ``_id`` field as follows: - -.. code-block:: json - :copyable: false - - { - "_id" : 2056, - "item" : "Cup", - "quantity" : 107 - } - -Additional Information ----------------------- - -For runnable examples of the update and replace operations, see the -following usage examples: - -- :ref:`golang-update-one` -- :ref:`golang-update-many` -- :ref:`golang-replace` - -To learn more about the operations mentioned, see the following -guides: - -- :ref:`golang-query-document` -- :ref:`golang-upsert` -- :ref:`golang-compound-operations` -- :manual:`Update Operators ` - -To learn more about updating array elements, see :ref:`golang-update-arrays`. - -API Documentation -~~~~~~~~~~~~~~~~~ - -To learn more about any of the methods or types discussed in this -guide, see the following API Documentation: - -- `WriteError <{+api+}/mongo#WriteError>`__ -- `UpdateOne() <{+api+}/mongo#Collection.UpdateOne>`__ -- `UpdateByID() <{+api+}/mongo#Collection.UpdateByID>`__ -- `UpdateMany() <{+api+}/mongo#Collection.UpdateMany>`__ -- `UpdateResult <{+api+}/mongo#UpdateResult>`__ -- `ReplaceOne() <{+api+}/mongo#Collection.ReplaceOne>`__ diff --git a/source/get-started.txt b/source/get-started.txt new file mode 100644 index 00000000..76d91eb3 --- /dev/null +++ b/source/get-started.txt @@ -0,0 +1,119 @@ +.. _go-get-started: + +======================== +Getting Started with Go +======================== + +.. facet:: + :name: genre + :values: tutorial + +.. meta:: + :description: Learn how to create an app to connect to MongoDB deployment by using the Go driver. + :keywords: go + +.. contents:: On this page + :local: + :backlinks: none + :depth: 1 + :class: singlecol + +.. adapted from quick start, should be checked + +.. include:: /includes/quick-start/overview.rst + +Set Up Your Project +------------------- + +.. procedure:: + :style: connected + + .. step:: Create and initialize your project + + Create a new directory and initialize your project by using ``go mod``, as + shown in the following commands: + + .. code-block:: shell + + mkdir go-quickstart + cd go-quickstart + go mod init go-quickstart + + .. step:: Add the {+driver-long+} as a dependency + + Use ``go get`` to add the {+driver-short+} as a dependency, as shown in + the following command: + + .. code-block:: shell + + go get go.mongodb.org/mongo-driver/v2/mongo + +Create a MongoDB Cluster +------------------------ + +.. include:: /includes/quick-start/atlas-setup.rst + +Query Your MongoDB Cluster from Your Application +------------------------------------------------ + +.. procedure:: + :style: connected + + .. step:: Add your connection string + + In your terminal, run the following command to create an environment + variable called ``MONGODB_URI`` and set your Atlas connection string as + its value: + + .. code-block:: bash + + export MONGODB_URI='' + + .. note:: + + Make sure to replace the ```` section of the connection + string with the password you created for your user that has + **atlasAdmin** permissions. + + .. step:: Create a new file + + Run the following command from the base directory of your project to + create a new file called ``main.go``: + + .. code-block:: shell + + touch main.go + + .. step:: Create your Go application + + Copy and paste the following code into your ``main.go`` file. This code + runs a query on your sample dataset in MongoDB Atlas. + + .. literalinclude:: /includes/quick-start/main.go + :language: go + :dedent: + + .. step:: Run your application + + Run the sample code with the following command from your command line: + + .. code-block:: bash + + go run main.go + + .. include:: /includes/quick-start/query-output.rst + + .. tip:: + + If you receive no output or an error, check whether you properly set up + your environment variable and ensure you have loaded the + :atlas:`sample datasets ` into your cluster. + +After you complete these steps, you have a working application that uses +the {+driver-long+} to connect to your MongoDB cluster, runs a query on the +sample data, and prints out the result. + +Next Steps +---------- + +.. include:: /includes/quick-start/next-steps.rst diff --git a/source/includes/connect/cluster-settings-client-options.go b/source/includes/connect/cluster-settings-client-options.go new file mode 100644 index 00000000..6975db6b --- /dev/null +++ b/source/includes/connect/cluster-settings-client-options.go @@ -0,0 +1,37 @@ +package main + +import ( + "context" + "log" + "os" + "time" + + "go.mongodb.org/mongo-driver/v2/mongo" + "go.mongodb.org/mongo-driver/v2/mongo/options" +) + +func main() { + uri := os.Getenv("MONGODB_URI") + if uri == "" { + log.Fatal("Set your 'MONGODB_URI' environment variable.") + } + + // Sets client options with cluster settings + // start-client-options + clientOptions := options.Client(). + ApplyURI(uri). + SetServerSelectionTimeout(10 * time.Second). + SetLocalThreshold(20 * time.Millisecond) + + client, err := mongo.Connect(clientOptions) + if err != nil { + log.Fatal(err) + } + // end-client-options + + defer func() { + if err = client.Disconnect(context.TODO()); err != nil { + log.Fatal(err) + } + }() +} diff --git a/source/includes/connect/cluster-settings-uri.go b/source/includes/connect/cluster-settings-uri.go new file mode 100644 index 00000000..1081a5b1 --- /dev/null +++ b/source/includes/connect/cluster-settings-uri.go @@ -0,0 +1,33 @@ +package main + +import ( + "context" + "fmt" + "log" + + "go.mongodb.org/mongo-driver/v2/mongo" + "go.mongodb.org/mongo-driver/v2/mongo/options" +) + +// Connection string with cluster settings options +// start-uri-variable +const uri = "mongodb://localhost:27017/?serverSelectionTimeoutMS=10000&localThresholdMS=20" + +// end-uri-variable + +func main() { + // Creates a new client and connects to the server + // start-apply-uri + client, err := mongo.Connect(options.Client().ApplyURI(uri)) + if err != nil { + log.Fatal(err) + } + // end-apply-uri + + fmt.Println("Connected to MongoDB with cluster settings options") + defer func() { + if err = client.Disconnect(context.TODO()); err != nil { + log.Fatal(err) + } + }() +} diff --git a/source/includes/connect/connection-pools-client-options.go b/source/includes/connect/connection-pools-client-options.go new file mode 100644 index 00000000..98a4fc48 --- /dev/null +++ b/source/includes/connect/connection-pools-client-options.go @@ -0,0 +1,39 @@ +package main + +import ( + "context" + "log" + "os" + "time" + + "go.mongodb.org/mongo-driver/v2/mongo" + "go.mongodb.org/mongo-driver/v2/mongo/options" +) + +func main() { + uri := os.Getenv("MONGODB_URI") + if uri == "" { + log.Fatal("Set your 'MONGODB_URI' environment variable.") + } + // start-client-options + // Sets client options with connection pool settings + clientOptions := options.Client(). + ApplyURI(uri). + SetMaxPoolSize(50). + SetMinPoolSize(10). + SetMaxConnIdleTime(30 * time.Second) + + // Creates a new client and connects to the server + client, err := mongo.Connect(clientOptions) + if err != nil { + log.Fatal(err) + } + // end-client-options + + // Ensures the client is disconnected when the function exits + defer func() { + if err = client.Disconnect(context.TODO()); err != nil { + log.Fatal(err) + } + }() +} diff --git a/source/includes/connect/connection-pools-uri.go b/source/includes/connect/connection-pools-uri.go new file mode 100644 index 00000000..8757ddf2 --- /dev/null +++ b/source/includes/connect/connection-pools-uri.go @@ -0,0 +1,31 @@ +package main + +import ( + "context" + "log" + + "go.mongodb.org/mongo-driver/v2/mongo" + "go.mongodb.org/mongo-driver/v2/mongo/options" +) + +// start-uri-variable +// Connection string with connection pool options +const uri = "mongodb://localhost:27017/?maxPoolSize=50&minPoolSize=10&maxIdleTimeMS=30000" + +// end-uri-variable +func main() { + // start-apply-uri + // Creates a new client and connects to the server + client, err := mongo.Connect(options.Client().ApplyURI(uri)) + if err != nil { + log.Fatal(err) + } + // end-apply-uri + + fmt.log("Connected to MongoDB with connection pool options") + defer func() { + if err = client.Disconnect(context.TODO()); err != nil { + log.Fatal(err) + } + }() +} diff --git a/source/includes/connect/csot.go b/source/includes/connect/csot.go new file mode 100644 index 00000000..4209d576 --- /dev/null +++ b/source/includes/connect/csot.go @@ -0,0 +1,59 @@ +package main + +import ( + "context" + "log" + "time" + + "go.mongodb.org/mongo-driver/v2/bson" + "go.mongodb.org/mongo-driver/v2/mongo" + "go.mongodb.org/mongo-driver/v2/mongo/options" +) + +func main() { + + // start-client-opts + opts := options.Client().SetTimeout(200 * time.Millisecond) + client, err := mongo.Connect(opts) + // end-client-opts + + if err != nil { + log.Fatal(err) + } + + // start-override + opts = options.Client().SetTimeout(200 * time.Millisecond) + client, err = mongo.Connect(opts) + if err != nil { + log.Fatal(err) + } + + coll := client.Database("db").Collection("people") + + ctx, cancel := context.WithTimeout(context.TODO(), 300*time.Millisecond) + defer cancel() + + _, err = coll.InsertOne(ctx, bson.D{{"name", "Agnes Georgiou"}}) + // end-override + + session, err := client.StartSession() + if err != nil { + log.Fatal(err) + } + defer session.EndSession(context.TODO()) + + // start-txn-context + txnContext, cancel := context.WithTimeout(context.TODO(), 300*time.Millisecond) + defer cancel() + + result, err := session.WithTransaction(txnContext, func(ctx context.Context) (string, error) { + // Perform transaction operations + }) + // end-txn-context + + defer func() { + if err = client.Disconnect(context.TODO()); err != nil { + log.Fatal(err) + } + }() +} diff --git a/source/includes/data-formats/ejson.go b/source/includes/data-formats/ejson.go new file mode 100644 index 00000000..96c1481d --- /dev/null +++ b/source/includes/data-formats/ejson.go @@ -0,0 +1,70 @@ +package main + +import ( + "fmt" + "log" + "time" + + "go.mongodb.org/mongo-driver/v2/bson" +) + +// begin-person-struct +type Person struct { + ID bson.ObjectID `bson:"_id"` + Name string + Age int + Birthday bson.DateTime + Address Address + Hobbies []string +} + +type Address struct { + Street string + City string + State string +} + +// end-person-struct + +func main() { + + // begin-unmarshal + var extJsonString = "{\"_id\":{\"$oid\":\"578f6fa2df35c7fbdbaed8c5\"},\"name\":\"Liana Ruiz\",\"age\":46,\"birthday\":{\"$date\":\"1988-01-15T00:00:00Z\"},\"address\":{\"street\":\"500 Slippery Rock Road\",\"city\":\"Round Rock\",\"state\":\"AR\"},\"hobbies\":[\"cycling\", \"baking\"]}" + + var p Person + err := bson.UnmarshalExtJSON([]byte(extJsonString), false, &p) + if err != nil { + log.Fatal(err) + } + + fmt.Printf("Go Struct Representation:\n%+v\n", p) + // end-unmarshal + + // begin-marshal + var person = Person{ + ID: bson.NewObjectID(), + Name: "Matteo Carisi", + Age: 49, + Birthday: bson.NewDateTimeFromTime(time.Date(1975, 10, 30, 0, 0, 0, 0, time.UTC)), + Address: Address{Street: "14a Corner Court", City: "Springfield", State: "IL"}, + Hobbies: []string{"cooking", "birdwatching"}, + } + + newExtJsonString, err := bson.MarshalExtJSON(person, false, true) + if err != nil { + log.Fatal(err) + } + + fmt.Printf("Extended JSON Representation:\n%s\n", newExtJsonString) + // end-marshal + + // begin-marshal-fmt + formattedString, err := bson.MarshalExtJSONIndent(person, false, true, "", " ") + if err != nil { + log.Fatal(err) + } + + fmt.Printf("%s\n", formattedString) + // end-marshal-fmt + +} diff --git a/source/includes/databases-collections.go b/source/includes/databases-collections.go new file mode 100644 index 00000000..4d2a0f2e --- /dev/null +++ b/source/includes/databases-collections.go @@ -0,0 +1,85 @@ +package main + +import ( + "context" + "fmt" + "log" + "os" + + "go.mongodb.org/mongo-driver/v2/bson" + "go.mongodb.org/mongo-driver/v2/mongo" + "go.mongodb.org/mongo-driver/v2/mongo/options" +) + +func main() { + uri := os.Getenv("MONGODB_URI") + docs := "www.mongodb.com/docs/drivers/go/current/" + if uri == "" { + log.Fatal("Set your 'MONGODB_URI' environment variable. " + + "See: " + docs + + "usage-examples/#environment-variable") + } + client, err := mongo.Connect(options.Client(). + ApplyURI(uri)) + if err != nil { + panic(err) + } + + defer func() { + if err := client.Disconnect(context.TODO()); err != nil { + panic(err) + } + }() + + // Accesses the test_database database + // start-access-database + database := client.Database("test_database") + // end-access-database + + // Accesses the test_collection collection + // start-access-collection + collection := database.Collection("test_collection") + // end-access-collection + fmt.Println("Collection accessed:", collection.Name()) + + // Explicitly creates a collection in the database + // start-create-collection + err = database.CreateCollection(context.TODO(), "example_collection") + if err != nil { + log.Fatalf("Failed to create collection: %v", err) + } + // end-create-collection + + // Retrieves information about each colllection in the database + // start-list-collections + cursor, err := database.ListCollections(context.TODO(), bson.D{}) + if err != nil { + log.Fatalf("Failed to list collections: %v", err) + } + defer cursor.Close(context.TODO()) + + for cursor.Next(context.TODO()) { + var collectionInfo bson.M + if err := cursor.Decode(&collectionInfo); err != nil { + log.Fatalf("Failed to decode collection info: %v", err) + } + if name, ok := collectionInfo["name"].(string); ok { + fmt.Println(name) + } else { + log.Println("Collection name not found or not a string") + } + } + + if err := cursor.Err(); err != nil { + log.Fatalf("Cursor error: %v", err) + } + // end-list-collections + + // Deletes the test_collection collection + // start-delete-collection + err = database.Collection("test_collection").Drop(context.TODO()) + if err != nil { + log.Fatalf("Failed to drop collection: %v", err) + } + // end-delete-collection +} diff --git a/source/includes/fundamentals/code-snippets/CRUD/changeStream.go b/source/includes/fundamentals/code-snippets/CRUD/changeStream.go index d8a4043f..8a333a93 100644 --- a/source/includes/fundamentals/code-snippets/CRUD/changeStream.go +++ b/source/includes/fundamentals/code-snippets/CRUD/changeStream.go @@ -23,7 +23,7 @@ type Course struct { func main() { var uri string if uri = os.Getenv("MONGODB_URI"); uri == "" { - log.Fatal("You must set your 'MONGODB_URI' environment variable. See\n\t https://www.mongodb.com/docs/drivers/go/current/usage-examples/#environment-variable") + log.Fatal("You must set your 'MONGODB_URI' environment variable. See\n\t https://www.mongodb.com/docs/drivers/go/current/connect/mongoclient/#environment-variable") } client, err := mongo.Connect(options.Client().ApplyURI(uri)) diff --git a/source/includes/fundamentals/code-snippets/CRUD/compoundOperations.go b/source/includes/fundamentals/code-snippets/CRUD/compoundOperations.go index a2fe6cca..2b334e5d 100644 --- a/source/includes/fundamentals/code-snippets/CRUD/compoundOperations.go +++ b/source/includes/fundamentals/code-snippets/CRUD/compoundOperations.go @@ -23,7 +23,7 @@ type Course struct { func main() { var uri string if uri = os.Getenv("MONGODB_URI"); uri == "" { - log.Fatal("You must set your 'MONGODB_URI' environment variable. See\n\t https://www.mongodb.com/docs/drivers/go/current/usage-examples/#environment-variable") + log.Fatal("You must set your 'MONGODB_URI' environment variable. See\n\t https://www.mongodb.com/docs/drivers/go/current/connect/mongoclient/#environment-variable") } client, err := mongo.Connect(options.Client().ApplyURI(uri)) diff --git a/source/includes/fundamentals/code-snippets/CRUD/delete.go b/source/includes/fundamentals/code-snippets/CRUD/delete.go index 482793d7..803310ce 100644 --- a/source/includes/fundamentals/code-snippets/CRUD/delete.go +++ b/source/includes/fundamentals/code-snippets/CRUD/delete.go @@ -24,7 +24,7 @@ type Book struct { func main() { var uri string if uri = os.Getenv("MONGODB_URI"); uri == "" { - log.Fatal("You must set your 'MONGODB_URI' environment variable. See\n\t https://www.mongodb.com/docs/drivers/go/current/usage-examples/#environment-variable") + log.Fatal("You must set your 'MONGODB_URI' environment variable. See\n\t https://www.mongodb.com/docs/drivers/go/current/connect/mongoclient/#environment-variable") } client, err := mongo.Connect(options.Client().ApplyURI(uri)) diff --git a/source/includes/fundamentals/code-snippets/CRUD/limit.go b/source/includes/fundamentals/code-snippets/CRUD/limit.go index fd0a078d..6fad89fb 100644 --- a/source/includes/fundamentals/code-snippets/CRUD/limit.go +++ b/source/includes/fundamentals/code-snippets/CRUD/limit.go @@ -23,7 +23,7 @@ type Course struct { func main() { var uri string if uri = os.Getenv("MONGODB_URI"); uri == "" { - log.Fatal("You must set your 'MONGODB_URI' environment variable. See\n\t https://www.mongodb.com/docs/drivers/go/current/usage-examples/#environment-variable") + log.Fatal("You must set your 'MONGODB_URI' environment variable. See\n\t https://www.mongodb.com/docs/drivers/go/current/connect/mongoclient/#environment-variable") } client, err := mongo.Connect(options.Client().ApplyURI(uri)) diff --git a/source/includes/fundamentals/code-snippets/CRUD/retrieve.go b/source/includes/fundamentals/code-snippets/CRUD/retrieve.go index 1001e735..f83c7ebf 100644 --- a/source/includes/fundamentals/code-snippets/CRUD/retrieve.go +++ b/source/includes/fundamentals/code-snippets/CRUD/retrieve.go @@ -25,7 +25,7 @@ type Tea struct { func main() { var uri string if uri = os.Getenv("MONGODB_URI"); uri == "" { - log.Fatal("You must set your 'MONGODB_URI' environment variable. See\n\t https://www.mongodb.com/docs/drivers/go/current/usage-examples/#environment-variable") + log.Fatal("You must set your 'MONGODB_URI' environment variable. See\n\t https://www.mongodb.com/docs/drivers/go/current/connect/mongoclient/#environment-variable") } client, err := mongo.Connect(options.Client().ApplyURI(uri)) diff --git a/source/includes/fundamentals/code-snippets/CRUD/retryableReadsWrites.go b/source/includes/fundamentals/code-snippets/CRUD/retryableReadsWrites.go new file mode 100644 index 00000000..95c6827e --- /dev/null +++ b/source/includes/fundamentals/code-snippets/CRUD/retryableReadsWrites.go @@ -0,0 +1,37 @@ +package main + +import ( + "context" + "log" + "os" + + "go.mongodb.org/mongo-driver/v2/mongo" + "go.mongodb.org/mongo-driver/v2/mongo/options" +) + +func main() { + var uri string + if uri = os.Getenv("MONGODB_URI"); uri == "" { + log.Fatal("You must set your 'MONGODB_URI' environment variable. See\n\t https://www.mongodb.com/docs/drivers/go/current/connect/mongoclient/#environment-variable") + } + + // start-retryable-example + // Defines the client options + clientOps := options.Client(). + ApplyURI(uri). + SetRetryWrites(false). + SetRetryReads(false) + + // Creates a new client using the specified options + client, err := mongo.Connect(clientOps) + if err != nil { + panic(err) + } + // end-retryable-example + + defer func() { + if err = client.Disconnect(context.TODO()); err != nil { + panic(err) + } + }() +} diff --git a/source/includes/fundamentals/code-snippets/CRUD/runCommand.go b/source/includes/fundamentals/code-snippets/CRUD/runCommand.go index 87e7b2f4..6dcdc41d 100644 --- a/source/includes/fundamentals/code-snippets/CRUD/runCommand.go +++ b/source/includes/fundamentals/code-snippets/CRUD/runCommand.go @@ -17,7 +17,7 @@ func main() { var uri string if uri = os.Getenv("MONGODB_URI"); uri == "" { - log.Fatal("You must set your 'MONGODB_URI' environment variable. See\n\t https://www.mongodb.com/docs/drivers/go/current/usage-examples/#environment-variable") + log.Fatal("You must set your 'MONGODB_URI' environment variable. See\n\t https://www.mongodb.com/docs/drivers/go/current/connect/mongoclient/#environment-variable") } client, err := mongo.Connect(options.Client().ApplyURI(uri)) diff --git a/source/includes/fundamentals/code-snippets/CRUD/skip.go b/source/includes/fundamentals/code-snippets/CRUD/skip.go index 42c8b4ac..0760598c 100644 --- a/source/includes/fundamentals/code-snippets/CRUD/skip.go +++ b/source/includes/fundamentals/code-snippets/CRUD/skip.go @@ -24,7 +24,7 @@ type Course struct { func main() { var uri string if uri = os.Getenv("MONGODB_URI"); uri == "" { - log.Fatal("You must set your 'MONGODB_URI' environment variable. See\n\t https://www.mongodb.com/docs/drivers/go/current/usage-examples/#environment-variable") + log.Fatal("You must set your 'MONGODB_URI' environment variable. See\n\t https://www.mongodb.com/docs/drivers/go/current/connect/mongoclient/#environment-variable") } client, err := mongo.Connect(options.Client().ApplyURI(uri)) diff --git a/source/includes/fundamentals/code-snippets/CRUD/sort.go b/source/includes/fundamentals/code-snippets/CRUD/sort.go index a56808cb..733ef1d7 100644 --- a/source/includes/fundamentals/code-snippets/CRUD/sort.go +++ b/source/includes/fundamentals/code-snippets/CRUD/sort.go @@ -24,7 +24,7 @@ type Course struct { func main() { var uri string if uri = os.Getenv("MONGODB_URI"); uri == "" { - log.Fatal("You must set your 'MONGODB_URI' environment variable. See\n\t https://www.mongodb.com/docs/drivers/go/current/usage-examples/#environment-variable") + log.Fatal("You must set your 'MONGODB_URI' environment variable. See\n\t https://www.mongodb.com/docs/drivers/go/current/connect/mongoclient/#environment-variable") } client, err := mongo.Connect(options.Client().ApplyURI(uri)) diff --git a/source/includes/fundamentals/code-snippets/indexes/atlasSearch.go b/source/includes/fundamentals/code-snippets/indexes/atlasSearch.go new file mode 100644 index 00000000..9e4c0d65 --- /dev/null +++ b/source/includes/fundamentals/code-snippets/indexes/atlasSearch.go @@ -0,0 +1,56 @@ +package main + +import ( + "context" + "fmt" + "time" + + "go.mongodb.org/mongo-driver/v2/bson" + "go.mongodb.org/mongo-driver/v2/mongo" + "go.mongodb.org/mongo-driver/v2/mongo/options" +) + +func main() { + var err error + // connect to the Atlas cluster + ctx := context.Background() + // Retrieves your Atlas connection string + uri := os.Getenv("MONGODB_ATLAS_URI") + if uri == "" { + log.Fatal("MONGODB_ATLAS_URI environment variable is not set") + } + client, err := mongo.Connect(options.Client().SetTimeout(5 * time.Second).ApplyURI(uri)) + if err != nil { + panic(err) + } + defer client.Disconnect(ctx) + + // set namespace + collection := client.Database("sample_mflix").Collection("movies") + + // begin-atlas-search + // Defines the pipeline + searchStage := bson.D{{"$search", bson.D{ + {"text", bson.D{ + {"path", "title"}, + {"query", "Alabama"}, + }}, + }}} + projectStage := bson.D{{"$project", bson.D{{"title", 1}}}} + + // Runs the pipeline + cursor, err := collection.Aggregate(ctx, mongo.Pipeline{searchStage, projectStage}) + if err != nil { + panic(err) + } + + // Prints the results + var results []bson.D + if err = cursor.All(ctx, &results); err != nil { + panic(err) + } + for _, result := range results { + fmt.Println(result) + } + // end-atlas-search +} diff --git a/source/includes/fundamentals/code-snippets/logging.go b/source/includes/fundamentals/code-snippets/logging.go index 8d1a1be6..4b252850 100644 --- a/source/includes/fundamentals/code-snippets/logging.go +++ b/source/includes/fundamentals/code-snippets/logging.go @@ -24,7 +24,7 @@ func main() { var uri string if uri = os.Getenv("MONGODB_URI"); uri == "" { - log.Fatal("You must set your 'MONGODB_URI' environment variable. See\n\t https://www.mongodb.com/docs/drivers/go/current/usage-examples/#environment-variable") + log.Fatal("You must set your 'MONGODB_URI' environment variable. See\n\t https://www.mongodb.com/docs/drivers/go/current/connect/mongoclient/#environment-variable") } //standardLogging(uri) //customLogging(uri) diff --git a/source/includes/fundamentals/code-snippets/srv.go b/source/includes/fundamentals/code-snippets/srv.go index b2df50aa..d59478c6 100644 --- a/source/includes/fundamentals/code-snippets/srv.go +++ b/source/includes/fundamentals/code-snippets/srv.go @@ -18,11 +18,13 @@ func main() { log.Fatal("You must set your 'MONGODB_URI' environment variable. See\n\t https://docs.mongodb.com/drivers/go/current/usage-examples/") } - // Use the SetServerAPIOptions() method to set the Stable API version to 1 + // Uses the SetServerAPIOptions() method to set the Stable API version to 1 serverAPI := options.ServerAPI(options.ServerAPIVersion1) + + // Defines the options for the MongoDB client opts := options.Client().ApplyURI(uri).SetServerAPIOptions(serverAPI) - // Create a new client and connect to the server + // Creates a new client and connects to the server client, err := mongo.Connect(opts) if err != nil { @@ -34,7 +36,7 @@ func main() { } }() - // Send a ping to confirm a successful connection + // Sends a ping to confirm a successful connection var result bson.M if err := client.Database("admin").RunCommand(context.TODO(), bson.D{{"ping", 1}}).Decode(&result); err != nil { panic(err) diff --git a/source/includes/fundamentals/code-snippets/tls.go b/source/includes/fundamentals/code-snippets/tls.go index 83b19b7d..c255d307 100644 --- a/source/includes/fundamentals/code-snippets/tls.go +++ b/source/includes/fundamentals/code-snippets/tls.go @@ -13,6 +13,7 @@ import ( func main() { + // start-tls caFile := "" certFile := "" keyFile := "" @@ -43,6 +44,7 @@ func main() { // Sets TLS options in options instance opts := options.Client().ApplyURI(uri).SetTLSConfig(tlsConfig) + // end-tls // Connects to MongoDB with TLS enabled client, err := mongo.Connect(opts) diff --git a/source/includes/localhost-connection.rst b/source/includes/localhost-connection.rst index c18be21a..1f536403 100644 --- a/source/includes/localhost-connection.rst +++ b/source/includes/localhost-connection.rst @@ -11,9 +11,9 @@ purposes, complete the following steps: .. important:: - Always secure your MongoDB server from malicious attacks. See our - :manual:`Security Checklist ` for a - list of security recommendations. + Always secure your MongoDB server from malicious attacks. See the + :manual:`Security Checklist ` in the + Server manual for a list of security recommendations. After you successfully start your MongoDB server, specify your connection string in your driver connection code. @@ -22,5 +22,6 @@ If your MongoDB Server is running locally, you can use the connection string ``"mongodb://localhost:"`` where ```` is the port number you configured your server to listen for incoming connections. -If you want to specify a different hostname or IP address, see our Server -Manual entry on :manual:`Connection Strings `. \ No newline at end of file +For more information on how to specify a different hostname or IP address, see +:manual:`Connection Strings ` in the Server +manual. \ No newline at end of file diff --git a/source/includes/usage-examples/code-snippets/bulk.go b/source/includes/usage-examples/code-snippets/bulk.go index 21a67a7e..f270c9fd 100644 --- a/source/includes/usage-examples/code-snippets/bulk.go +++ b/source/includes/usage-examples/code-snippets/bulk.go @@ -13,7 +13,7 @@ import ( "go.mongodb.org/mongo-driver/v2/mongo/options" ) -// start-restaurant-struct +// Defines a Restaurant struct as a model for documents in the "restaurants" collection type Restaurant struct { Name string RestaurantId string `bson:"restaurant_id,omitempty"` @@ -23,8 +23,6 @@ type Restaurant struct { Grades []interface{} `bson:"grades,omitempty"` } -// end-restaurant-struct - func main() { if err := godotenv.Load(); err != nil { log.Println("No .env file found") @@ -32,7 +30,7 @@ func main() { var uri string if uri = os.Getenv("MONGODB_URI"); uri == "" { - log.Fatal("You must set your 'MONGODB_URI' environment variable. See\n\t https://www.mongodb.com/docs/drivers/go/current/usage-examples/#environment-variable") + log.Fatal("You must set your 'MONGODB_URI' environment variable. See\n\t https://www.mongodb.com/docs/drivers/go/current/connect/mongoclient/#environment-variable") } client, err := mongo.Connect(options.Client().ApplyURI(uri)) @@ -45,7 +43,6 @@ func main() { } }() - // begin bulk coll := client.Database("sample_restaurants").Collection("restaurants") // Creates write models that specify replace and update operations @@ -61,13 +58,12 @@ func main() { // Runs a bulk write operation for the specified write operations results, err := coll.BulkWrite(context.TODO(), models, opts) - // end bulk if err != nil { panic(err) } - // When you run this file for the first time, it should print: + // When you run this file for the first time, it should print output similar to the following: // Number of documents replaced or modified: 2 fmt.Printf("Number of documents replaced or modified: %d", results.ModifiedCount) } diff --git a/source/includes/usage-examples/code-snippets/command.go b/source/includes/usage-examples/code-snippets/command.go index 67f0bd0e..85803a86 100644 --- a/source/includes/usage-examples/code-snippets/command.go +++ b/source/includes/usage-examples/code-snippets/command.go @@ -21,7 +21,7 @@ func main() { var uri string if uri = os.Getenv("MONGODB_URI"); uri == "" { - log.Fatal("You must set your 'MONGODB_URI' environment variable. See\n\t https://www.mongodb.com/docs/drivers/go/current/usage-examples/#environment-variable") + log.Fatal("You must set your 'MONGODB_URI' environment variable. See\n\t https://www.mongodb.com/docs/drivers/go/current/connect/mongoclient/#environment-variable") } client, err := mongo.Connect(options.Client().ApplyURI(uri)) diff --git a/source/includes/usage-examples/code-snippets/count.go b/source/includes/usage-examples/code-snippets/count.go index 068d862b..b2a81fdf 100644 --- a/source/includes/usage-examples/code-snippets/count.go +++ b/source/includes/usage-examples/code-snippets/count.go @@ -20,7 +20,7 @@ func main() { var uri string if uri = os.Getenv("MONGODB_URI"); uri == "" { - log.Fatal("You must set your 'MONGODB_URI' environment variable. See\n\t https://www.mongodb.com/docs/drivers/go/current/usage-examples/#environment-variable") + log.Fatal("You must set your 'MONGODB_URI' environment variable. See\n\t https://www.mongodb.com/docs/drivers/go/current/connect/mongoclient/#environment-variable") } client, err := mongo.Connect(options.Client().ApplyURI(uri)) diff --git a/source/includes/usage-examples/code-snippets/deleteMany.go b/source/includes/usage-examples/code-snippets/deleteMany.go index b208e54f..0bcc60a3 100644 --- a/source/includes/usage-examples/code-snippets/deleteMany.go +++ b/source/includes/usage-examples/code-snippets/deleteMany.go @@ -20,7 +20,7 @@ func main() { var uri string if uri = os.Getenv("MONGODB_URI"); uri == "" { - log.Fatal("You must set your 'MONGODB_URI' environment variable. See\n\t https://www.mongodb.com/docs/drivers/go/current/usage-examples/#environment-variable") + log.Fatal("You must set your 'MONGODB_URI' environment variable. See\n\t https://www.mongodb.com/docs/drivers/go/current/connect/mongoclient/#environment-variable") } client, err := mongo.Connect(options.Client().ApplyURI(uri)) diff --git a/source/includes/usage-examples/code-snippets/deleteOne.go b/source/includes/usage-examples/code-snippets/deleteOne.go index 9362c7cb..8d23b987 100644 --- a/source/includes/usage-examples/code-snippets/deleteOne.go +++ b/source/includes/usage-examples/code-snippets/deleteOne.go @@ -20,7 +20,7 @@ func main() { var uri string if uri = os.Getenv("MONGODB_URI"); uri == "" { - log.Fatal("You must set your 'MONGODB_URI' environment variable. See\n\t https://www.mongodb.com/docs/drivers/go/current/usage-examples/#environment-variable") + log.Fatal("You must set your 'MONGODB_URI' environment variable. See\n\t https://www.mongodb.com/docs/drivers/go/current/connect/mongoclient/#environment-variable") } client, err := mongo.Connect(options.Client().ApplyURI(uri)) diff --git a/source/includes/usage-examples/code-snippets/distinct.go b/source/includes/usage-examples/code-snippets/distinct.go index b8a18bbb..f3f0a6af 100644 --- a/source/includes/usage-examples/code-snippets/distinct.go +++ b/source/includes/usage-examples/code-snippets/distinct.go @@ -20,7 +20,7 @@ func main() { var uri string if uri = os.Getenv("MONGODB_URI"); uri == "" { - log.Fatal("You must set your 'MONGODB_URI' environment variable. See\n\t https://www.mongodb.com/docs/drivers/go/current/usage-examples/#environment-variable") + log.Fatal("You must set your 'MONGODB_URI' environment variable. See\n\t https://www.mongodb.com/docs/drivers/go/current/connect/mongoclient/#environment-variable") } client, err := mongo.Connect(options.Client().ApplyURI(uri)) diff --git a/source/includes/usage-examples/code-snippets/find.go b/source/includes/usage-examples/code-snippets/find.go index af0bf4e3..a70573c8 100644 --- a/source/includes/usage-examples/code-snippets/find.go +++ b/source/includes/usage-examples/code-snippets/find.go @@ -34,7 +34,7 @@ func main() { var uri string if uri = os.Getenv("MONGODB_URI"); uri == "" { - log.Fatal("You must set your 'MONGODB_URI' environment variable. See\n\t https://www.mongodb.com/docs/drivers/go/current/usage-examples/#environment-variable") + log.Fatal("You must set your 'MONGODB_URI' environment variable. See\n\t https://www.mongodb.com/docs/drivers/go/current/connect/mongoclient/#environment-variable") } client, err := mongo.Connect(options.Client().ApplyURI(uri)) diff --git a/source/includes/usage-examples/code-snippets/findOne.go b/source/includes/usage-examples/code-snippets/findOne.go index 31f66530..e3ba4447 100644 --- a/source/includes/usage-examples/code-snippets/findOne.go +++ b/source/includes/usage-examples/code-snippets/findOne.go @@ -34,7 +34,7 @@ func main() { var uri string if uri = os.Getenv("MONGODB_URI"); uri == "" { - log.Fatal("You must set your 'MONGODB_URI' environment variable. See\n\t https://www.mongodb.com/docs/drivers/go/current/usage-examples/#environment-variable") + log.Fatal("You must set your 'MONGODB_URI' environment variable. See\n\t https://www.mongodb.com/docs/drivers/go/current/connect/mongoclient/#environment-variable") } client, err := mongo.Connect(options.Client().ApplyURI(uri)) diff --git a/source/includes/usage-examples/code-snippets/insertMany.go b/source/includes/usage-examples/code-snippets/insertMany.go index 13750c3f..577dab73 100644 --- a/source/includes/usage-examples/code-snippets/insertMany.go +++ b/source/includes/usage-examples/code-snippets/insertMany.go @@ -31,7 +31,7 @@ func main() { var uri string if uri = os.Getenv("MONGODB_URI"); uri == "" { - log.Fatal("You must set your 'MONGODB_URI' environment variable. See\n\t https://www.mongodb.com/docs/drivers/go/current/usage-examples/#environment-variable") + log.Fatal("You must set your 'MONGODB_URI' environment variable. See\n\t https://www.mongodb.com/docs/drivers/go/current/connect/mongoclient/#environment-variable") } client, err := mongo.Connect(options.Client().ApplyURI(uri)) diff --git a/source/includes/usage-examples/code-snippets/insertOne.go b/source/includes/usage-examples/code-snippets/insertOne.go index fc2b5c7d..41493f85 100644 --- a/source/includes/usage-examples/code-snippets/insertOne.go +++ b/source/includes/usage-examples/code-snippets/insertOne.go @@ -31,7 +31,7 @@ func main() { var uri string if uri = os.Getenv("MONGODB_URI"); uri == "" { - log.Fatal("You must set your 'MONGODB_URI' environment variable. See\n\t https://www.mongodb.com/docs/drivers/go/current/usage-examples/#environment-variable") + log.Fatal("You must set your 'MONGODB_URI' environment variable. See\n\t https://www.mongodb.com/docs/drivers/go/current/connect/mongoclient/#environment-variable") } client, err := mongo.Connect(options.Client().ApplyURI(uri)) diff --git a/source/includes/usage-examples/code-snippets/insertOneBsonD.go b/source/includes/usage-examples/code-snippets/insertOneBsonD.go new file mode 100644 index 00000000..e69de29b diff --git a/source/includes/usage-examples/code-snippets/replace.go b/source/includes/usage-examples/code-snippets/replace.go index d2e1aeb9..84328efe 100644 --- a/source/includes/usage-examples/code-snippets/replace.go +++ b/source/includes/usage-examples/code-snippets/replace.go @@ -32,7 +32,7 @@ func main() { var uri string if uri = os.Getenv("MONGODB_URI"); uri == "" { - log.Fatal("You must set your 'MONGODB_URI' environment variable. See\n\t https://www.mongodb.com/docs/drivers/go/current/usage-examples/#environment-variable") + log.Fatal("You must set your 'MONGODB_URI' environment variable. See\n\t https://www.mongodb.com/docs/drivers/go/current/connect/mongoclient/#environment-variable") } client, err := mongo.Connect(options.Client().ApplyURI(uri)) diff --git a/source/includes/usage-examples/code-snippets/struct-tag.go b/source/includes/usage-examples/code-snippets/struct-tag.go index ea6f5bd8..b5d55dd1 100644 --- a/source/includes/usage-examples/code-snippets/struct-tag.go +++ b/source/includes/usage-examples/code-snippets/struct-tag.go @@ -34,7 +34,7 @@ func main() { var uri string if uri = os.Getenv("MONGODB_URI"); uri == "" { - log.Fatal("You must set your 'MONGODB_URI' environment variable. See\n\t https://www.mongodb.com/docs/drivers/go/current/usage-examples/#environment-variable") + log.Fatal("You must set your 'MONGODB_URI' environment variable. See\n\t https://www.mongodb.com/docs/drivers/go/current/connect/mongoclient/#environment-variable") } client, err := mongo.Connect(options.Client().ApplyURI(uri)) diff --git a/source/includes/usage-examples/code-snippets/updateMany.go b/source/includes/usage-examples/code-snippets/updateMany.go index 1acf729b..9577c3ef 100644 --- a/source/includes/usage-examples/code-snippets/updateMany.go +++ b/source/includes/usage-examples/code-snippets/updateMany.go @@ -13,6 +13,25 @@ import ( "go.mongodb.org/mongo-driver/v2/mongo/options" ) +// Defines a Restaurant struct as a model for documents in the "restaurants" collection +type Restaurant struct { + ID bson.ObjectID `bson:"_id"` + Name string `bson:"name"` + Cuisine string `bson:"cuisine"` + AverageRating float64 `bson:"avg_rating,omitempty"` +} + +// Create a filter struct to specify the documents to update +type UpdateManyRestaurantFilter struct { + Cuisine string `bson:"cuisine"` + Borough string `bson:"borough"` +} + +// Defines a RestaurantUpdate struct to specify the fields to update +type RestaurantUpdateMany struct { + AverageRating float64 `bson:"avg_rating"` +} + func main() { if err := godotenv.Load(); err != nil { log.Println("No .env file found") @@ -20,7 +39,7 @@ func main() { var uri string if uri = os.Getenv("MONGODB_URI"); uri == "" { - log.Fatal("You must set your 'MONGODB_URI' environment variable. See\n\t https://www.mongodb.com/docs/drivers/go/current/usage-examples/#environment-variable") + log.Fatal("You must set your 'MONGODB_URI' environment variable. See\n\t https://www.mongodb.com/docs/drivers/go/current/connect/mongoclient/#environment-variable") } client, err := mongo.Connect(options.Client().ApplyURI(uri)) @@ -33,24 +52,25 @@ func main() { } }() - // begin updatemany - coll := client.Database("sample_airbnb").Collection("listingsAndReviews") - filter := bson.D{{"address.market", "Sydney"}} + coll := client.Database("sample_restaurants").Collection("restaurants") + filter := UpdateManyRestaurantFilter{ + Cuisine: "Pizza", + Borough: "Brooklyn", + } - // Creates instructions to update the values of the "price" field - update := bson.D{{"$mul", bson.D{{"price", 1.15}}}} + // Creates instructions to update the values of the "AverageRating" field + update := bson.D{{"$set", RestaurantUpdateMany{AverageRating: 4.5}}} - // Updates documents in which the value of the "address.market" - // field is "Sydney" + // Updates documents in which the value of the "Cuisine" + // field is "Pizza" result, err := coll.UpdateMany(context.TODO(), filter, update) if err != nil { panic(err) } - // end updatemany // Prints the number of updated documents fmt.Printf("Documents updated: %v\n", result.ModifiedCount) - // When you run this file for the first time, it should print: - // Number of documents replaced: 609 + // When you run this file for the first time, it should print output similar to the following: + // Documents updated: 296 } diff --git a/source/includes/usage-examples/code-snippets/updateManyBson.go b/source/includes/usage-examples/code-snippets/updateManyBson.go new file mode 100644 index 00000000..f4f2178a --- /dev/null +++ b/source/includes/usage-examples/code-snippets/updateManyBson.go @@ -0,0 +1,54 @@ +// Updates documents that match a query filter by using the Go driver +package main + +import ( + "context" + "fmt" + "log" + "os" + + "github.com/joho/godotenv" + "go.mongodb.org/mongo-driver/v2/bson" + "go.mongodb.org/mongo-driver/v2/mongo" + "go.mongodb.org/mongo-driver/v2/mongo/options" +) + +func main() { + if err := godotenv.Load(); err != nil { + log.Println("No .env file found") + } + + var uri string + if uri = os.Getenv("MONGODB_URI"); uri == "" { + log.Fatal("You must set your 'MONGODB_URI' environment variable. See\n\t https://www.mongodb.com/docs/drivers/go/current/connect/mongoclient/#environment-variable") + } + + client, err := mongo.Connect(options.Client().ApplyURI(uri)) + if err != nil { + panic(err) + } + defer func() { + if err = client.Disconnect(context.TODO()); err != nil { + panic(err) + } + }() + + coll := client.Database("sample_restaurants").Collection("restaurants") + filter := bson.D{{"cuisine", "Pizza"}, {"borough", "Brooklyn"}} + + // Creates instructions to update the values of the "avg_rating" field + update := bson.D{{"$set", bson.D{{"avg_rating", 4.5}}}} + + // Updates documents in which the value of the "cuisine" field is "Pizza" + // and the value of the "borough" field is "Brooklyn" + result, err := coll.UpdateMany(context.TODO(), filter, update) + if err != nil { + panic(err) + } + + // Prints the number of updated documents + fmt.Printf("Documents updated: %v\n", result.ModifiedCount) + + // When you run this file for the first time, it should print output similar to the following: + // Documents updated: 296 +} diff --git a/source/includes/usage-examples/code-snippets/updateOne.go b/source/includes/usage-examples/code-snippets/updateOne.go index 825cd1a6..83edc509 100644 --- a/source/includes/usage-examples/code-snippets/updateOne.go +++ b/source/includes/usage-examples/code-snippets/updateOne.go @@ -13,6 +13,23 @@ import ( "go.mongodb.org/mongo-driver/v2/mongo/options" ) +// Defines a Restaurant struct as a model for documents in the "restaurants" collection +type Restaurant struct { + ID bson.ObjectID `bson:"_id"` + Name string `bson:"name"` + AverageRating float64 `bson:"avg_rating,omitempty"` +} + +// Create a filter struct to specify the document to update +type UpdateRestaurantFilter struct { + ID bson.ObjectID `bson:"_id"` +} + +// Defines a RestaurantUpdate struct to specify the fields to update +type RestaurantUpdate struct { + AverageRating float64 `bson:"avg_rating"` +} + func main() { if err := godotenv.Load(); err != nil { log.Println("No .env file found") @@ -20,7 +37,7 @@ func main() { var uri string if uri = os.Getenv("MONGODB_URI"); uri == "" { - log.Fatal("You must set your 'MONGODB_URI' environment variable. See\n\t https://www.mongodb.com/docs/drivers/go/current/usage-examples/#environment-variable") + log.Fatal("You must set your 'MONGODB_URI' environment variable. See\n\t https://www.mongodb.com/docs/drivers/go/current/connect/mongoclient/#environment-variable") } client, err := mongo.Connect(options.Client().ApplyURI(uri)) @@ -33,24 +50,23 @@ func main() { } }() - // begin updateone coll := client.Database("sample_restaurants").Collection("restaurants") - id, _ := bson.ObjectIDFromHex("5eb3d668b31de5d588f42a7a") - filter := bson.D{{"_id", id}} + + id, _ := bson.ObjectIDFromHex("5eb3d668b31de5d588f4292b") + filter := UpdateRestaurantFilter{ID: id} // Creates instructions to add the "avg_rating" field to documents - update := bson.D{{"$set", bson.D{{"avg_rating", 4.4}}}} + update := bson.D{{"$set", RestaurantUpdate{AverageRating: 4.4}}} // Updates the first document that has the specified "_id" value result, err := coll.UpdateOne(context.TODO(), filter, update) if err != nil { panic(err) } - // end updateone // Prints the number of updated documents fmt.Printf("Documents updated: %v\n", result.ModifiedCount) - // When you run this file for the first time, it should print: - // Number of documents replaced: 1 + // When you run this file for the first time, it should print output similar to the following: + // Documents updated: 1 } diff --git a/source/includes/usage-examples/code-snippets/updateOneBson.go b/source/includes/usage-examples/code-snippets/updateOneBson.go new file mode 100644 index 00000000..250ab3c2 --- /dev/null +++ b/source/includes/usage-examples/code-snippets/updateOneBson.go @@ -0,0 +1,54 @@ +// Updates the first document that matches a query filter by using the Go driver +package main + +import ( + "context" + "fmt" + "log" + "os" + + "github.com/joho/godotenv" + "go.mongodb.org/mongo-driver/v2/bson" + "go.mongodb.org/mongo-driver/v2/mongo" + "go.mongodb.org/mongo-driver/v2/mongo/options" +) + +func main() { + if err := godotenv.Load(); err != nil { + log.Println("No .env file found") + } + + var uri string + if uri = os.Getenv("MONGODB_URI"); uri == "" { + log.Fatal("You must set your 'MONGODB_URI' environment variable. See\n\t https://www.mongodb.com/docs/drivers/go/current/connect/mongoclient/#environment-variable") + } + + client, err := mongo.Connect(options.Client().ApplyURI(uri)) + if err != nil { + panic(err) + } + defer func() { + if err = client.Disconnect(context.TODO()); err != nil { + panic(err) + } + }() + + coll := client.Database("sample_restaurants").Collection("restaurants") + id, _ := bson.ObjectIDFromHex("5eb3d668b31de5d588f42a7a") + filter := bson.D{{"_id", id}} + + // Creates instructions to add the "avg_rating" field to documents + update := bson.D{{"$set", bson.D{{"avg_rating", 4.4}}}} + + // Updates the first document that has the specified "_id" value + result, err := coll.UpdateOne(context.TODO(), filter, update) + if err != nil { + panic(err) + } + + // Prints the number of updated documents + fmt.Printf("Documents updated: %v\n", result.ModifiedCount) + + // When you run this file for the first time, it should print output similar to the following: + // Documents updated: 1 +} diff --git a/source/includes/usage-examples/code-snippets/watch.go b/source/includes/usage-examples/code-snippets/watch.go index bb81b8f0..9fa2ec03 100644 --- a/source/includes/usage-examples/code-snippets/watch.go +++ b/source/includes/usage-examples/code-snippets/watch.go @@ -21,7 +21,7 @@ func main() { var uri string if uri = os.Getenv("MONGODB_URI"); uri == "" { - log.Fatal("You must set your 'MONGODB_URI' environment variable. See\n\t https://www.mongodb.com/docs/drivers/go/current/usage-examples/#environment-variable") + log.Fatal("You must set your 'MONGODB_URI' environment variable. See\n\t https://www.mongodb.com/docs/drivers/go/current/connect/mongoclient/#environment-variable") } client, err := mongo.Connect(options.Client().ApplyURI(uri)) diff --git a/source/includes/usage-examples/example-intro.rst b/source/includes/usage-examples/example-intro.rst new file mode 100644 index 00000000..66e0e306 --- /dev/null +++ b/source/includes/usage-examples/example-intro.rst @@ -0,0 +1,10 @@ +.. note:: Example Setup + + This example connects to an instance of MongoDB by using a + connection URI. To learn more about connecting to your MongoDB + instance, see the :ref:`golang-mongoclient` guide. This example + also uses the ``restaurants`` collection in the ``sample_restaurants`` database + included in the :atlas:`Atlas sample datasets `. You + can load them into your database on the free tier of MongoDB Atlas + by following the :atlas:`Get Started with Atlas Guide + `. \ No newline at end of file diff --git a/source/index.txt b/source/index.txt index 536b2048..e958abc9 100644 --- a/source/index.txt +++ b/source/index.txt @@ -10,25 +10,30 @@ :description: Learn how to use the MongoDB Go Driver. :keywords: landing page, index +.. TODO cleanup + .. toctree:: :titlesonly: :maxdepth: 1 - Quick Start - Quick Reference - What's New - Usage Examples - Fundamentals + Get Started + Connect + Context Package + Databases & Collections + CRUD Operations + Aggregation + Data Formats + Indexes + Run a Database Command + Atlas Search + Atlas Vector Search + Monitoring & Logging + Security + Reference API Documentation <{+api+}/mongo> - FAQ - Connection Troubleshooting Issues & Help - Compatibility View the Source -.. - /upgrade - Introduction ------------ @@ -51,6 +56,12 @@ Quick Start Learn how to establish a connection to MongoDB Atlas and begin working with data in the :ref:`golang-quickstart` section. +Databases and Collections +------------------------- + +Learn how to interact with MongoDB databases and collections in the +:ref:`golang-databases-collections` section. + Quick Reference --------------- diff --git a/source/fundamentals/indexes.txt b/source/indexes.txt similarity index 100% rename from source/fundamentals/indexes.txt rename to source/indexes.txt diff --git a/source/monitoring-and-logging.txt b/source/monitoring-and-logging.txt new file mode 100644 index 00000000..e0972dad --- /dev/null +++ b/source/monitoring-and-logging.txt @@ -0,0 +1,25 @@ +.. _golang-monitoring-logging: + +====================== +Monitoring and Logging +====================== + +.. meta:: + :keywords: event + :description: Learn how to monitor and log events by using the {+driver-long+}. + +.. toctree:: + + Monitoring + Logging + Change Streams + +Overview +-------- + +Learn how to set up monitoring and logging for your application in the following +sections: + +- :doc:`/monitoring-and-logging/monitoring` +- :doc:`/monitoring-and-logging/logging` +- :doc:`/monitoring-and-logging/change-streams` diff --git a/source/monitoring-and-logging/change-streams.txt b/source/monitoring-and-logging/change-streams.txt new file mode 100644 index 00000000..d72add1f --- /dev/null +++ b/source/monitoring-and-logging/change-streams.txt @@ -0,0 +1,298 @@ +.. _golang-watch-changes: +.. _golang-monitor-changes: +.. _golang-watch: + +================================ +Monitor Data with Change Streams +================================ + +.. facet:: + :name: genre + :values: reference + +.. meta:: + :keywords: code example, delta + :description: Learn how to monitor document changes in MongoDB by using change streams, including opening streams and modifying output with pipelines and options. + +.. contents:: On this page + :local: + :backlinks: none + :depth: 2 + :class: singlecol + +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 MongoDB Server feature that +allows your application to subscribe to data changes on a collection, database, +or deployment. + +A change stream outputs new change events, providing access to real-time data +changes. You can open a change stream on a collection, database, or client +object. + +Sample Data +~~~~~~~~~~~ + +The examples in this guide use the following ``Course`` struct as a model for +documents in the ``courses`` collection: + +.. literalinclude:: /includes/fundamentals/code-snippets/CRUD/changeStream.go + :start-after: begin struct + :end-before: end struct + :language: go + :dedent: + +To run the examples in this guide, load these documents into the ``courses`` +collection in the ``db`` database by using the following snippet: + +.. literalinclude:: /includes/fundamentals/code-snippets/CRUD/changeStream.go + :language: go + :dedent: + :start-after: begin insertDocs + :end-before: end insertDocs + +.. include:: /includes/fundamentals/automatic-db-coll-creation.rst + +Each document contains a description of a university course that includes the +course title and maximum enrollment, corresponding to the ``title`` and +``enrollment`` fields in each document. + +.. note:: + + Each example output shows truncated ``_data``, ``clusterTime``, and + ``ObjectID`` values because the driver generates them uniquely. + +Open a Change Stream +-------------------- + +You can watch for changes in MongoDB by using the ``Watch()`` method on the +following objects: + +- **Collection**: Monitor changes to a specific collection +- **Database**: Monitor changes to all collections in a database +- **MongoClient**: Monitor changes across all databases + +For each object, the ``Watch()`` method opens a change stream to emit change +event documents when they occur. + +The ``Watch()`` method requires a context parameter and a pipeline parameter. To +return all changes, pass in an empty ``Pipeline`` object. + +The ``Watch()`` method optionally takes an aggregation pipeline which consists +of an array of aggregation stages as the first parameter. The aggregation stages +filter and transform the change events. + +Example +~~~~~~~ + +The following example opens a change stream on the ``courses`` collection and +prints the change stream events as they occur: + +.. literalinclude:: /includes/fundamentals/code-snippets/CRUD/changeStream.go + :language: go + :dedent: + :start-after: begin open stream + :end-before: end open stream + +If you modify the ``courses`` collection in a separate program or shell, this +code prints your changes as they occur. Inserting a document with a ``title`` +value of ``"Advanced Screenwriting"`` and an ``enrollment`` value of ``20`` +results in the following change event: + +.. code-block:: none + :copyable: false + + map[_id:map[_data:...] clusterTime: {...} + documentKey:map[_id:ObjectID("...")] fullDocument:map[_id:ObjectID("...") + enrollment:20 title:Advanced Screenwriting] ns: map[coll:courses db:db] + operationType:insert] + +To view a fully runnable example, see :ref:`Open a Change Stream Example: +Full File ` section in this guide. + +Filter Change Events +~~~~~~~~~~~~~~~~~~~~ + +Use the pipeline parameter to modify the change stream output. This parameter +allows you to only watch for certain change events. Format the pipeline +parameter as an array of documents, with each document representing an +aggregation stage. + +You can use the following pipeline stages in this parameter: + +- ``$addFields`` +- ``$match`` +- ``$project`` +- ``$replaceRoot`` +- ``$replaceWith`` +- ``$redact`` +- ``$set`` +- ``$unset`` + +The following example opens a change stream on the ``db`` database but only +watches for new delete operations: + +.. literalinclude:: /includes/fundamentals/code-snippets/CRUD/changeStream.go + :language: go + :dedent: + :start-after: begin delete events + :end-before: end delete events + +.. note:: + + The ``Watch()`` method was called on the ``db`` database, so the code outputs + new delete operations on any collection within this database. + +.. _golang-usageex-monitor-changes: +.. _golang-change-streams-full-file: + +Open a Change Stream Example: Full File +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. include:: /includes/usage-examples/example-intro.rst + +The following example opens a change stream on the ``restaurants`` collection +and prints inserted documents: + +.. literalinclude:: /includes/usage-examples/code-snippets/watch.go + :start-after: begin watch + :end-before: end watch + :emphasize-lines: 7 + :language: go + :dedent: + +View a `fully runnable example. <{+example+}/watch.go>`__ + +Expected Result +^^^^^^^^^^^^^^^ + +.. TODO - when porting over all usage examples, ensure this link is correct. + +After you run the full example, run the :ref:`Insert a Document full file +example ` in a different shell. When you run the insert +operation, you see output similar to the following: + +.. code-block:: json + :copyable: false + + // results truncated { + "_id": ..., "name": "8282", "cuisine": "Korean" + } + +.. important:: + + When you finish working with this usage example, make sure to shut it down by + closing your terminal. + +Configure Change Stream Options +------------------------------- + +Use the ``options`` parameter to modify the behavior of the ``Watch()`` method. + +You can specify the following options for the ``Watch()`` method: + +- ``ResumeAfter`` +- ``StartAfter`` +- ``FullDocument`` +- ``FullDocumentBeforeChange`` +- ``BatchSize`` +- ``MaxAwaitTime`` +- ``Collation`` +- ``StartAtOperationTime`` +- ``Comment`` +- ``ShowExpandedEvents`` +- ``Custom`` +- ``CustomPipeline`` + +For more information on these options, see the :manual:`db.collection.watch() ` +entry in the Server manual. + +Pre- and Post-Images +~~~~~~~~~~~~~~~~~~~~ + +When you perform any CRUD operation on a collection, by default, the +corresponding change event document contains only the delta of the fields +modified by the operation. You can see the full document before and after a +change, in addition to the delta, by specifying settings in the ``options`` +parameter of the ``Watch()`` method. + +If you want to see a document's **post-image**, the full version of the document +after a change, set the ``FullDocument`` field of the ``options`` parameter to +one of the following values: + +- ``UpdateLookup``: The change event document includes a copy of the entire + changed document. +- ``WhenAvailable``: The change event document includes a post-image of the + modified document for change events if the post-image is available. +- ``Required``: The output is the same as for ``WhenAvailable``, but the driver + raises a server-side error if the post-image is not available. + +If you want to see a document's **pre-image**, the full version of the document +before a change, set the ``FullDocumentBeforeChange`` field of the ``options`` +parameter to one of the following values: + +- ``WhenAvailable``: The change event document includes a pre-image of the + modified document for change events if the pre-image is available. +- ``Required``: The output is the same as for ``WhenAvailable``, but the driver + raises a server-side error if the pre-image is not available. + +.. important:: + + To access document pre- and post-images, you must enable + ``changeStreamPreAndPostImages`` for the collection. See the :manual:`Change + Streams + ` + section of the collMod Database Command guide in the MongoDB Server manual + for instructions and more information. + +.. note:: + + There is no pre-image for an inserted document and no post-image for a deleted document. + +Example +~~~~~~~~ + +The following example calls the ``Watch()`` method on the ``courses`` +collection. It specifies a value for the ``FullDocument`` field of the +``options`` parameter to output a copy of the entire modified document, instead +of only the changed fields: + +.. literalinclude:: /includes/fundamentals/code-snippets/CRUD/changeStream.go + :language: go + :dedent: + :start-after: begin full document + :end-before: end full document + +Updating the ``enrollment`` value of the document with the ``title`` of ``"World +Fiction"`` from ``35`` to ``30`` results in the following change event: + +.. code-block:: none + :copyable: false + + {"_id": {"_data": "..."},"operationType": "update","clusterTime": + {"$timestamp": {"t":"...","i":"..."}},"fullDocument": {"_id": + {"$oid":"..."},"title": "World Fiction","enrollment": {"$numberInt":"30"}}, + "ns": {"db": "db","coll": "courses"},"documentKey": {"_id": {"$oid":"..."}}, + "updateDescription": {"updatedFields": {"enrollment": {"$numberInt":"30"}}, + "removedFields": [],"truncatedArrays": []}} + +Without specifying the ``FullDocument`` option, the same update operation no +longer outputs the ``"fullDocument"`` value in the change event document. + +Additional Information +---------------------- + +For more information on change streams, see :manual:`Change Streams +` in the Server manual. + +API Documentation +~~~~~~~~~~~~~~~~~ + +To learn more about the ``Watch()`` method, see the following API +documentation: + +- `Watch() for collections <{+api+}/mongo#Collection.Watch>`__ +- `Watch() for databases <{+api+}/mongo#Database.Watch>`__ +- `Watch() for clients <{+api+}/mongo#Client.Watch>`__ \ No newline at end of file diff --git a/source/fundamentals/logging.txt b/source/monitoring-and-logging/logging.txt similarity index 100% rename from source/fundamentals/logging.txt rename to source/monitoring-and-logging/logging.txt diff --git a/source/monitoring-and-logging/monitoring.txt b/source/monitoring-and-logging/monitoring.txt new file mode 100644 index 00000000..2966a6c4 --- /dev/null +++ b/source/monitoring-and-logging/monitoring.txt @@ -0,0 +1,857 @@ +.. _golang-monitoring: + +========================== +Monitor Application Events +========================== + +.. contents:: On this page + :local: + :backlinks: none + :depth: 3 + :class: singlecol + +.. meta:: + :description: Explore cluster, command, and connection pool monitoring in the MongoDB Go Driver. + +.. facet:: + :name: genre + :values: reference + +.. meta:: + :keywords: event + :description: Learn how to monitor events by using the {+driver-long+}. + +Overview +-------- + +In this guide, you can learn how to set up and configure **monitoring** in the +{+driver-long+}. You can monitor **events** by using the {+driver-short+} to +subscribe to them in your application. + +Monitoring involves collecting information about the activities of a running +program, which you can use with an application performance management +library. + +An event is any action that occurs within the driver during its operation. The +{+driver-short+} includes functionality for listening to a subset of these +events. + +Monitoring the {+driver-short+} lets you understand the driver's resource usage +and performance, and can help you make informed decisions when designing and +debugging your application. + +In this guide you will learn how to perform these tasks: + +- :ref:`Monitor Command Events ` +- :ref:`Monitor Server Discovery and Monitoring (SDAM) Events ` +- :ref:`Monitor Connection Pool Events ` + +This guide shows how to use information about the activity of the driver in code. +To learn how to record events in the driver, see the {+driver-short+}'s +:ref:`Logging ` guide. + +.. _golang-command-monitoring: + +Monitor Command Events +---------------------- + +A command event is an event related to a MongoDB database command. You can +access one or more command monitoring events by using the driver to subscribe to +them in your application. + +To learn more about MongoDB database commands, see the +:manual:`Database Commands ` guide in the Server Manual. + +Subscribe to Events +~~~~~~~~~~~~~~~~~~~ + +You can access details about command events by subscribing to them +in your application. The following example demonstrates how to subscribe +to the ``CommandStartedEvent`` event by instantiating a +``CommandMonitor`` and connecting to a deployment: + +.. code-block:: go + + var eventArray []*event.CommandStartedEvent + cmdMonitor := &event.CommandMonitor{ + Started: func(ctx context.Context, e *event.CommandStartedEvent) { + eventArray = append(eventArray, e) + }, + } + clientOpts := options.Client().ApplyURI(uri).SetMonitor(cmdMonitor) + client, err := mongo.Connect(clientOpts) + +Event Descriptions +~~~~~~~~~~~~~~~~~~ + +You can subscribe to one or more of the following command monitoring +events: + +.. list-table:: + :widths: 33 67 + :header-rows: 1 + + * - Event Name + - Description + + * - ``CommandStartedEvent`` + - Created when a command starts. + + * - ``CommandSucceededEvent`` + - Created when a command succeeds. + + * - ``CommandFailedEvent`` + - Created when a command does not succeed. + +Example Event Documents +~~~~~~~~~~~~~~~~~~~~~~~ + +The following sections show sample output for each type of command monitoring event. + +CommandStartedEvent +``````````````````` + +.. code-block:: none + :copyable: false + + *event.CommandStartedEvent + { + "Command": "...", + "DatabaseName": "...", + "CommandName": "...", + "RequestID": ..., + "ConnectionID": "...", + "ServerConnectionID": ..., + "ServiceID": "..." + } + +CommandSucceededEvent +````````````````````` + +.. code-block:: none + :copyable: false + + *event.CommandSucceededEvent + { + "DurationNanos": 38717583, + "Duration": 38717583, + "CommandName": "insert", + "RequestID": 13, + "ConnectionID": "...", + "ServerConnectionID": ..., + "ServiceID": null, + "Reply": "..." + } + +CommandFailedEvent +`````````````````` + +.. code-block:: none + :copyable: false + + *event.CommandFailedEvent + { + "DurationNanos": 38717583, + "Duration": 38717583, + "CommandName": "insert", + "RequestID": 13, + "ConnectionID": "...", + "ServerConnectionID": ..., + "ServiceID": null, + "Failure": "..." + } + +.. _golang-cluster-monitoring: + +Monitor Server Discovery and Monitoring Events +---------------------------------------------- + +The {+driver-short+} creates topology events, also known as SDAM events, when +there is a change in the state of the instance or cluster that you connected to. +For example, the driver creates an event when you establish a new connection or +if the cluster elects a new primary node. + +The following sections demonstrate how to record topology changes in your application +and explore the information provided in these events. + +Subscribe to Events +~~~~~~~~~~~~~~~~~~~ + +You can access details about SDAM events by subscribing to them +in your application. The following example demonstrates how to subscribe +to the ``ServerClosed`` event by instantiating a +``ServerMonitor`` and connecting to a deployment: + +.. code-block:: go + + var eventArray []*event.ServerClosedEvent + srvMonitor := &event.ServerMonitor{ + ServerClosed: func(e *event.ServerClosedEvent) { + eventArray = append(eventArray, e) + }, + } + clientOpts := options.Client().ApplyURI(uri).SetServerMonitor(srvMonitor) + client, err := mongo.Connect(clientOpts) + +Event Descriptions +~~~~~~~~~~~~~~~~~~ + +You can subscribe to the following SDAM events by specifying properties +of a ``ServerMonitor`` instance: + +.. list-table:: + :widths: 35 65 + :header-rows: 1 + + * - Event Name + - Description + + * - ``ServerDescriptionChangedEvent`` + - Created when an instance state changes (such as from secondary to primary). + + * - ``ServerOpeningEvent`` + - Created when the server is initialized. + + * - ``ServerClosedEvent`` + - Created when the server is closed. + + * - ``TopologyDescriptionChangedEvent`` + - Created when the topology changes, such as an election of a new + primary or disconnection of a ``mongos`` proxy. + + * - ``TopologyOpeningEvent`` + - Created when the topology is initialized. + + * - ``TopologyClosedEvent`` + - Created when the topology is closed. + + * - ``ServerHeartbeatStartedEvent`` + - Created when the heartbeat is started. + + * - ``ServerHeartbeatSucceededEvent`` + - Created when the heartbeat succeeds. + + * - ``ServerHeartbeatFailedEvent`` + - Created when the heartbeat fails. + +Example Event Documents +~~~~~~~~~~~~~~~~~~~~~~~ + +The following sections show sample output for each type of SDAM event. + +ServerDescriptionChangedEvent +````````````````````````````` + +.. code-block:: none + :copyable: false + + *event.ServerDescriptionChangedEvent + { + "Address": "...", + "TopologyID": "...", + "PreviousDescription": { + "Addr": "...", + "Arbiters": null, + "AverageRTT": 0, + "AverageRTTSet": false, + "Compression": null, + "CanonicalAddr": "...", + "ElectionID": "...", + "HeartbeatInterval": 0, + "HelloOK": false, + "Hosts": null, + "LastError": null, + "LastUpdateTime": "...", + "LastWriteTime": "...", + "MaxBatchCount": 0, + "MaxDocumentSize": 0, + "MaxMessageSize": 0, + "Members": null, + "Passives": null, + "Passive": false, + "Primary": "...", + "ReadOnly": false, + "ServiceID": null, + "SessionTimeoutMinutes": 0, + "SetName": "...", + "SetVersion": 0, + "Tags": null, + "TopologyVersion": null, + "Kind": 0, + "WireVersion": null + }, + "NewDescription": { + "Addr": "...", + "Arbiters": null, + "AverageRTT": ..., + "AverageRTTSet": true, + "Compression": null, + "CanonicalAddr": "...", + "ElectionID": "...", + "HeartbeatInterval": ..., + "HelloOK": true, + "Hosts": [...], + "LastError": null, + "LastUpdateTime": "...", + "LastWriteTime": "...", + "MaxBatchCount": ..., + "MaxDocumentSize": ..., + "MaxMessageSize": ..., + "Members": [...], + "Passives": null, + "Passive": false, + "Primary": "...", + "ReadOnly": false, + "ServiceID": null, + "SessionTimeoutMinutes": 30, + "SetName": "...", + "SetVersion": 9, + "Tags": [...], + "TopologyVersion": {...}, + "Kind": 10, + "WireVersion": {...} + } + } + +.. _golang-monitoring-kind-field: + +``Kind`` Field Value +++++++++++++++++++++ + +The ``Kind`` field in an event document represents the type of a +single server in a topology and can have the following values: + +.. list-table:: + :widths: 30 70 + :header-rows: 1 + + * - Value + - Description + * - ``0`` + - Unknown instance + * - ``1`` + - Standalone instance + * - ``2`` + - Replica set member + * - ``6`` + - Primary instance + * - ``10`` + - Secondary instance + * - ``18`` + - Arbiter instance + * - ``34`` + - Replica set ghost (a member that cannot be queried) + * - ``256`` + - ``mongos`` proxy instance + * - ``512`` + - Load balancer instance + +ServerOpeningEvent +`````````````````` + +.. code-block:: none + :copyable: false + + *event.ServerOpeningEvent + { + "Address": "...", + "TopologyID": "..." + } + +ServerClosedEvent +````````````````` + +.. code-block:: none + :copyable: false + + *event.ServerClosedEvent + { + "Address": "...", + "TopologyID": "..." + } + +TopologyDescriptionChangedEvent +``````````````````````````````` + +.. important:: + + Because the driver calls ``TopologyDescriptionChangedEvent`` when the + deployment topology is locked, the callback (function argument) for this event + must not attempt any operation that requires server selection on + the same client. + +.. code-block:: none + :copyable: false + + *event.TopologyDescriptionChangedEvent + { + "TopologyID": "...", + "PreviousDescription": { + "Servers": [ + { + "Addr": "...", + "Arbiters": null, + "AverageRTT": 0, + "AverageRTTSet": false, + "Compression": null, + "CanonicalAddr": "...", + "ElectionID": "...", + "HeartbeatInterval": 0, + "HelloOK": false, + "Hosts": null, + "LastError": null, + "LastUpdateTime": "...", + "LastWriteTime": "...", + "MaxBatchCount": 0, + "MaxDocumentSize": 0, + "MaxMessageSize": 0, + "Members": null, + "Passives": null, + "Passive": false, + "Primary": "...", + "ReadOnly": false, + "ServiceID": null, + "SessionTimeoutMinutes": 0, + "SetName": "...", + "SetVersion": 0, + "Tags": null, + "TopologyVersion": null, + "Kind": 0, + "WireVersion": null + }, + ... + ], + "SetName": "...", + "Kind": 10, + "SessionTimeoutMinutes": 30, + "CompatibilityErr": null + }, + "NewDescription": { + "Servers": [...], + "SetName": "...", + "Kind": 10, + "SessionTimeoutMinutes": 30, + "CompatibilityErr": null + } + } + +To interpret the value of the ``Kind`` field, see the :ref:`Kind Field +Value section `. + +TopologyOpeningEvent +```````````````````` + +.. code-block:: none + :copyable: false + + *event.TopologyOpeningEvent + { + "TopologyID": "..." + } + +TopologyClosedEvent +``````````````````` + +.. code-block:: none + :copyable: false + + *event.TopologyClosedEvent + { + "TopologyID": "..." + } + +ServerHeartbeatStartedEvent +``````````````````````````` + +.. code-block:: none + :copyable: false + + *event.ServerHeartbeatStartedEvent + { + "ConnectionID": "...", + "Awaited": true + } + +ServerHeartbeatSucceededEvent +````````````````````````````` + +.. code-block:: none + :copyable: false + + *event.ServerHeartbeatSucceededEvent + { + "DurationNanos": ..., + "Reply": { + "Addr": "...", + "Arbiters": null, + "AverageRTT": 0, + "AverageRTTSet": false, + "Compression": null, + "CanonicalAddr": "...", + "ElectionID": "...", + "HeartbeatInterval": 0, + "HelloOK": true, + "Hosts": [...], + "LastError": null, + "LastUpdateTime": "...", + "LastWriteTime": "...", + "MaxBatchCount": ..., + "MaxDocumentSize": ..., + "MaxMessageSize": ..., + "Members": [...], + "Passives": null, + "Passive": false, + "Primary": "...", + "ReadOnly": false, + "ServiceID": null, + "SessionTimeoutMinutes": 30, + "SetName": "...", + "SetVersion": 9, + "Tags": [...], + "TopologyVersion": {...}, + "Kind": 6, + "WireVersion": {...} + }, + "ConnectionID": "...", + "Awaited": true + } + +To interpret the value of the ``Kind`` field, see the :ref:`Kind Field +Value section `. + +ServerHeartbeatFailedEvent +`````````````````````````` + +.. code-block:: none + :copyable: false + + *event.ServerHeartbeatFailedEvent + { + "DurationNanos": ..., + "Failure": "" + "ConnectionID": "...", + "Awaited": true + } + +.. _golang-connection-pool-monitoring: + +Monitor Connection Pool Events +------------------------------ + +A connection pool is a set of open TCP connections that your driver maintains with a +MongoDB instance. Connection pools help reduce the number of network handshakes +your application needs to perform and can help your application run faster. + +The following sections demonstrate how to record connection pool events in your +application and explore the information provided in these events. + +Subscribe to Events +~~~~~~~~~~~~~~~~~~~ + +You can access details about connection pool events by subscribing to them +in your application. The following example demonstrates how to subscribe +to the ``PoolEvent`` event by instantiating a +``PoolMonitor`` and connecting to a deployment: + +.. code-block:: go + + var eventArray []*event.PoolEvent + cxnMonitor := &event.PoolMonitor{ + Started: func(e *event.PoolEvent) { + eventArray = append(eventArray, e) + }, + } + clientOpts := options.Client().ApplyURI(uri).SetPoolMonitor(cxnMonitor) + client, err := mongo.Connect(clientOpts) + +Event Descriptions +~~~~~~~~~~~~~~~~~~ + +The following table describes the types of pool events that the driver +emits: + +.. list-table:: + :widths: 33 67 + :header-rows: 1 + + * - Pool Event Type + - Description + + * - ``ConnectionPoolCreated`` + - Created when a connection pool is created. + + * - ``ConnectionPoolReady`` + - Created when a connection pool is ready. + + * - ``ConnectionPoolCleared`` + - Created when all the connections in the pool are closed. + + * - ``ConnectionPoolClosed`` + - Created when a connection pool is closed, before the destruction of + the server instance. + + * - ``ConnectionCreated`` + - Created when a connection is created, but not necessarily + when it is used for an operation. + + * - ``ConnectionReady`` + - Created after a connection completes a + handshake and is ready to be used for operations. + + * - ``ConnectionClosed`` + - Created when a connection is closed. + + * - ``ConnectionCheckOutStarted`` + - Created when an operation attempts to acquire a connection for + execution. + + * - ``ConnectionCheckOutFailed`` + - Created when an operation cannot acquire a connection for + execution. + + * - ``ConnectionCheckedOut`` + - Created when an operation successfully acquires a connection for + execution. + + * - ``ConnectionCheckedIn`` + - Created when a connection is checked back into the pool after an operation + is executed. + +Example Event Documents +~~~~~~~~~~~~~~~~~~~~~~~ + +The following sections show sample output for each type of connection +pool monitoring event. + +ConnectionPoolCreated +````````````````````` + +.. code-block:: none + :copyable: false + + *event.PoolEvent + { + "type": "ConnectionPoolCreated", + "address": "...", + "connectionId": 0, + "options": { + "maxPoolSize": 100, + "minPoolSize": 0, + "maxIdleTimeMS": 0 + }, + "reason": "", + "serviceId": null, + "error": null + } + +ConnectionPoolReady +``````````````````` + +.. code-block:: none + :copyable: false + + *event.PoolEvent + { + "type": "ConnectionPoolReady", + "address": "...", + "connectionId": 0, + "options": null, + "reason": "", + "serviceId": null, + "error": null + } + +ConnectionPoolCleared +````````````````````` + +.. code-block:: none + :copyable: false + + *event.PoolEvent + { + "type": "ConnectionPoolCleared", + "address": "...", + "connectionId": 0, + "options": null, + "reason": "", + "serviceId": null, + "error": null + } + +ConnectionPoolClosed +```````````````````` + +.. code-block:: none + :copyable: false + + *event.PoolEvent + { + "type": "ConnectionPoolClosed", + "address": "...", + "connectionId": 0, + "options": null, + "reason": "", + "serviceId": null, + "error": null + } + +ConnectionCreated +````````````````` + +.. code-block:: none + :copyable: false + + *event.PoolEvent + { + "type": "ConnectionCreated", + "address": "...", + "connectionId": 1, + "options": null, + "reason": "", + "serviceId": null, + "error": null + } + +ConnectionReady +```````````````` + +.. code-block:: none + :copyable: false + + *event.PoolEvent + { + "type": "ConnectionReady", + "address": "...", + "connectionId": 1, + "options": null, + "reason": "", + "serviceId": null, + "error": null + } + +ConnectionClosed +````````````````` + +.. code-block:: none + :copyable: false + + *event.PoolEvent + { + "type": "ConnectionClosed", + "address": "...", + "connectionId": 1, + "options": null, + "reason": "", + "serviceId": null, + "error": null + } + +ConnectionCheckOutStarted +````````````````````````` + +.. code-block:: none + :copyable: false + + *event.PoolEvent + { + "type": "ConnectionCheckOutStarted", + "address": "...", + "connectionId": 0, + "options": null, + "reason": "", + "serviceId": null, + "error": null + } + +ConnectionCheckOutFailed +```````````````````````` + +.. code-block:: none + :copyable: false + + *event.PoolEvent + { + "type": "ConnectionCheckOutFailed", + "address": "...", + "connectionId": 0, + "options": null, + "reason": "", + "serviceId": null, + "error": null + } + +ConnectionCheckedOut +````````````````````` + +.. code-block:: none + :copyable: false + + *event.PoolEvent + { + "type": "ConnectionCheckedOut", + "address": "...", + "connectionId": 1, + "options": null, + "reason": "", + "serviceId": null, + "error": null + } + +ConnectionCheckedIn +``````````````````` + +.. code-block:: none + :copyable: false + + *event.PoolEvent + { + "type": "ConnectionCheckedIn", + "address": "...", + "connectionId": 1, + "options": null, + "reason": "", + "serviceId": null, + "error": null + } + +Additional Information +---------------------- + +To learn more about monitoring a MongoDB deployment, see the :website:`How +to Monitor MongoDB +` article. + +To learn more about connecting to MongoDB, see the +:ref:`golang-connection-guide`. + +To learn more about performing MongoDB operations, see the +:ref:`golang-crud` guides. + +API Documentation +~~~~~~~~~~~~~~~~~ + +To learn more about the methods and types mentioned in this +guide, see the following API documentation: + +- `event <{+api+}/event>`__ package + +Command Events +`````````````` + +- `CommandMonitor <{+api+}/event#CommandMonitor>`__ type +- `SetMonitor() <{+api+}/mongo/options#ClientOptions.SetMonitor>`__ method +- `CommandStartedEvent <{+api+}/event#CommandStartedEvent>`__ type +- `CommandSucceededEvent <{+api+}/event#CommandSucceededEvent>`__ type +- `CommandFailedEvent <{+api+}/event#CommandFailedEvent>`__ type + +SDAM Events +``````````` +- `ServerMonitor <{+api+}/event#ServerMonitor>`__ type +- `SetServerMonitor() <{+api+}/mongo/options#ClientOptions.SetServerMonitor>`__ method + +Connection Pool Events +`````````````````````` + +- `PoolMonitor <{+api+}/event#PoolMonitor>`__ type +- `PoolEvent <{+api+}/event#PoolEvent>`__ type +- `SetPoolMonitor() <{+api+}/mongo/options#ClientOptions.SetPoolMonitor>`__ method diff --git a/source/reference.txt b/source/reference.txt new file mode 100644 index 00000000..9819683b --- /dev/null +++ b/source/reference.txt @@ -0,0 +1,16 @@ +.. _golang-reference: + +========== +Reference +========== + +.. toctree:: + :titlesonly: + :maxdepth: 1 + + Release Notes + Compatibility + Upgrade Guides + Previous Versions + Quick Reference + \ No newline at end of file diff --git a/source/reference/compatibility.txt b/source/reference/compatibility.txt new file mode 100644 index 00000000..3333cc07 --- /dev/null +++ b/source/reference/compatibility.txt @@ -0,0 +1,36 @@ +.. _golang-compatibility: + +============= +Compatibility +============= + +.. meta:: + :description: Check the recommended MongoDB Go Driver versions for compatibility with different MongoDB server versions. + +.. contents:: On this page + :local: + :backlinks: none + :depth: 2 + :class: singlecol + +MongoDB Compatibility +--------------------- + +The following compatibility table specifies the recommended version 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-go.rst + +Language Compatibility +---------------------- + +.. include:: /includes/language-compatibility-table-go.rst + +For more information on how to read the compatibility tables, see our guide on +:ref:`MongoDB Compatibility Tables. ` diff --git a/source/reference/previous-versions.txt b/source/reference/previous-versions.txt new file mode 100644 index 00000000..e9caea9c --- /dev/null +++ b/source/reference/previous-versions.txt @@ -0,0 +1 @@ +.. TODO verify if needed \ No newline at end of file diff --git a/source/reference/quick-reference.txt b/source/reference/quick-reference.txt new file mode 100644 index 00000000..aabf724b --- /dev/null +++ b/source/reference/quick-reference.txt @@ -0,0 +1,469 @@ +.. _golang-quick-reference: + +=============== +Quick Reference +=============== + +.. meta:: + :keywords: code example, summary, copyable + :description: See simple code examples for how to perform a variety of operations in the Go driver. + +This page shows the driver syntax for several MongoDB operations in the +{+driver-short+} and provides links to related reference and API +documentation. + +.. list-table:: + :header-rows: 1 + :widths: 25 75 + + * - Operation + - Syntax + + * - | **Find a Document** + | + | `API Documentation <{+api+}/mongo#Collection.FindOne>`__ + | :ref:`Find Documents Guide ` + + - .. io-code-block:: + :copyable: true + + .. input:: + :language: go + + err = coll.FindOne(context.TODO(), bson.D{{"firstName", Mike}}).Decode(&result) + + .. output:: + :language: go + :visible: false + + [{firstName Mike}, {lastName Smith} ...] + + * - | **Find Multiple Documents** + | + | `API Documentation <{+api+}/mongo#Collection.Find>`__ + | :ref:`Find Documents Guide ` + + - .. io-code-block:: + :copyable: true + + .. input:: + :language: go + + cursor, err := coll.Find(context.TODO(), bson.D{{"age", bson.D{{"$gte", 46}}}}) + + .. output:: + :language: go + :visible: false + + [{firstName Kyle}, {age 51}, ... ] + [{firstName Omar}, {age 47}, ... ] + + * - | **Insert a Document** + | + | `API Documentation <{+api+}/mongo#Collection.InsertOne>`__ + | :ref:`Insert Documents Guide ` + + - .. code-block:: go + :copyable: true + + result, err := coll.InsertOne( + context.TODO(), + bson.D{ + {"firstName", "Aliya"}, + {"lastName", "Sanders"} + } + ) + + * - | **Insert Multiple Documents** + | + | `API Documentation <{+api+}/mongo#Collection.InsertMany>`__ + | :ref:`Insert Documents Guide ` + + - .. code-block:: go + :copyable: true + + docs := []interface{} { + bson.D{{"firstName", "Erik"}, {"age", 27}}, + bson.D{{"firstName", "Mohammad"}, {"lastName", "Ahmad"}, {"age", 10}}, + bson.D{{"firstName", "Todd"}}, + bson.D{{"firstName", "Juan"}, {"lastName", "Pablo"}} + } + + result, err := coll.InsertMany(context.TODO(), docs) + + * - | **Update a Document** + | + | `API Documentation <{+api+}/mongo#Collection.UpdateOne>`__ + | :ref:`Update Documents Guide ` + + - .. io-code-block:: + :copyable: true + + .. input:: + :language: go + + result, err := coll.UpdateOne( + context.TODO(), + bson.D{{"firstName", "Erik"}}, + bson.D{{"$set", bson.D{{"age", 28}}}} + ) + fmt.Printf("Number of modified documents: %d\n", result.ModifiedCount) + + .. output:: + :language: go + :visible: false + + Number of modified documents: 1 + + * - | **Update Multiple Documents** + | + | `API Documentation <{+api+}/mongo#Collection.UpdateMany>`__ + | :ref:`Update Documents Guide ` + + - .. io-code-block:: + :copyable: true + + .. input:: + :language: go + + result, err := coll.UpdateMany( + context.TODO(), + bson.D{{"age", bson.D{{"$gte", 65}}}}, + bson.D{{"$set", bson.D{{"classification", "senior"}}}} + ) + fmt.Printf("Number of modified documents: %d\n", result.ModifiedCount) + + .. output:: + :language: go + :visible: false + + Number of modified documents: 4 + + * - | **Update Arrays in Documents** + | + | `API Documentation <{+api+}/mongo#Collection.UpdateMany>`__ + | :ref:`Update Arrays Guide ` + + - .. io-code-block:: + :copyable: true + + .. input:: + :language: go + + result, err := coll.UpdateMany( + context.TODO(), + bson.D{}, + bson.D{{"$push", bson.D{{"hobbies", "painting"}}}} + ) + + .. output:: + :language: go + :visible: false + + [{firstName Xiao}, {hobbies ["painting"]}, ... ] + [{firstName Omar}, {hobbies ["kayaking", "painting"]}, ... ] + ... + + * - | **Replace a Document** + | + | `API Documentation <{+api+}/mongo#Collection.ReplaceOne>`__ + | :ref:`Replace Documents Guide ` + + - .. io-code-block:: + :copyable: true + + .. input:: + :language: go + + result, err := coll.ReplaceOne( + context.TODO(), + bson.D{{"firstName", "Mick"}, {"lastName", "Salazar"}}, + bson.D{{"firstName", "Michael"}, {"lastName", "Salazar Jr."}} + ) + + .. output:: + :language: go + :visible: false + + [{{firstName Michael}, {lastName Salazar Jr.} }] + + * - | **Delete a Document** + | + | `API Documentation <{+api+}/mongo#Collection.DeleteOne>`__ + | :ref:`Delete Documents Guide ` + + - .. code-block:: go + :copyable: true + + result, err := coll.DeleteOne( + context.TODO(), + bson.D{{"firstName", "Xiao"}} + ) + + * - | **Delete Multiple Documents** + | + | `API Documentation <{+api+}/mongo#Collection.DeleteMany>`__ + | :ref:`Delete Documents Guide ` + + - .. code-block:: go + :copyable: true + + results, err := coll.DeleteMany( + context.TODO(), + bson.D{{"age", bson.D{{"$lte", 12}}}} + ) + + * - | **Bulk Write** + | + | `API Documentation <{+api+}/mongo#Collection.BulkWrite>`__ + | :ref:`Bulk Operations Guide ` + + - .. io-code-block:: + :copyable: true + + .. input:: + :language: go + + models := []mongo.WriteModel{ + mongo.NewInsertOneModel().SetDocument(bson.D{{"firstName", "John"}, {"age", 5}}), + mongo.NewUpdateOneModel().SetFilter(bson.D{{"firstName", "Juan"}}). + SetUpdate(bson.D{{"$set", bson.D{{"age", 12}}}}), + } + opts := options.BulkWrite().SetOrdered(true) + + results, err := coll.BulkWrite(context.TODO(), models, opts) + + .. output:: + :language: go + :visible: false + + [{firstName John}, {age 5} ... ] + [{firstName Juan}, {age 12} ... ] + + * - | **Monitor Data Changes** + | + | `API Documentation <{+api+}/mongo#Collection.Watch>`__ + | :ref:`Change Streams Guide ` + + - .. code-block:: go + :copyable: true + + pipeline := mongo.Pipeline{bson.D{{"$match", bson.D{{"operationType", "insert"}}}}} + cs, err := coll.Watch(context.TODO(), pipeline) + + * - | **Access Data from a Cursor Iteratively** + | + | `API Documentation <{+api+}/mongo#Cursor.Next>`__ + | :ref:`Retrieve Documents Individually Reference ` + + - .. io-code-block:: + :copyable: true + + .. input:: + :language: go + + cursor, err := coll.Find(context.TODO(), bson.D{}) + + for cursor.Next(context.TODO()) { + var result bson.D + if err := cursor.Decode(&result); err != nil { + log.Fatal(err) + } + fmt.Println(result) + } + + .. output:: + :language: go + :visible: false + + [{firstName Doug} ... ] + [{firstName Erik} ...] + [{firstName Oleg} ...] + ... + + * - | **Access Data from a Cursor as an Array** + | + | `API Documentation <{+api+}/mongo#Cursor.All>`__ + | :ref:`Retrieve All Documents Reference ` + + - .. io-code-block:: + :copyable: true + + .. input:: + :language: go + + cursor, err := coll.Find(context.TODO(), bson.D{}) + + var results []bson.D + if err = cursor.All(context.TODO(), &results); err != nil { + panic(err) + } + + .. output:: + :language: go + :visible: false + + [{firstName Mike} ... ] + [{firstName Edgar} ...] + [{firstName Freddie} ...] + ... + + * - | **Count Documents** + | + | `API Documentation <{+api+}/mongo#Collection.CountDocuments>`__ + | :ref:`Count Documents Guide ` + + - .. io-code-block:: + :copyable: true + + .. input:: + :language: go + + count, err := coll.CountDocuments(context.TODO(), bson.D{}) + + .. output:: + :language: go + :visible: false + + 17 + + * - | **List Distinct Field Values** + | + | `API Documentation <{+api+}/mongo#Collection.Distinct>`__ + | :ref:`Distinct Values Guide ` + + - .. io-code-block:: + :copyable: true + + .. input:: + :language: go + + var results []string + err = coll.Distinct(context.TODO(), "firstName", bson.D{}).Decode(&results) + + .. output:: + :language: go + :visible: false + + [Mike Xiao Sandy ...] + + * - | **Limit the Number of Documents Retrieved** + | + | `API Documentation <{+api+}/mongo/options#FindOptionsBuilder.SetLimit>`__ + | :ref:`Limit Documents Reference ` + + - .. io-code-block:: + :copyable: true + + .. input:: + :language: go + + cursor, err := coll.Find(context.TODO(), bson.D{}, options.Find().SetLimit(2)) + + .. output:: + :language: go + :visible: false + + [{firstName Xiao} ... ] + [{firstName Oleg} ...] + + * - | **Skip Retrieved Documents** + | + | `API Documentation <{+api+}/mongo/options#FindOptionsBuilder.SetSkip>`__ + | :ref:`Skip Documents Reference ` + + - .. io-code-block:: + :copyable: true + + .. input:: + :language: go + + // the collection has 6 documents + cursor, err := coll.Find(context.TODO(), bson.D{}, options.Find().SetSkip(4)) + + .. output:: + :language: go + :visible: false + + [{firstName Sandy} ... ] + [{firstName Michael} ...] + + * - | **Sort Retrieved Documents** + | + | `API Documentation <{+api+}/mongo/options#FindOptionsBuilder.SetSort>`__ + | :ref:`Sort Documents Reference ` + + - .. io-code-block:: + :copyable: true + + .. input:: + :language: go + + cursor, err := coll.Find(context.TODO(), bson.D{}, options.Find().SetSort(bson.D{{"age", 1}})) + + .. output:: + :language: go + :visible: false + + [{firstName Dev} {age 5} ... ] + [{firstName Jose} {age 7} ... ] + [{firstName Om} {age 8} ... ] + + * - | **Project Document Fields in Results** + | + | `API Documentation <{+api+}/mongo/options#FindOptionsBuilder.SetProjection>`__ + | :ref:`Projection Guide ` + + - .. io-code-block:: + :copyable: true + + .. input:: + :language: go + + cursor, err := coll.Find( + context.TODO(), + bson.D{}, + options.Find().SetProjection( + bson.D{{"age", 0}, {"_id",0}} + ) + ) + + .. output:: + :language: go + :visible: false + + [{firstName Lester} {lastName Franklin}] + [{firstName Wendall} {lastName Griffin}] + ... + + * - | **Create an Index** + | + | `API Documentation <{+api+}/mongo#IndexView.CreateOne>`__ + | :ref:`Indexes Guide ` + + - .. code-block:: go + :copyable: true + + model := mongo.IndexModel{Keys: bson.D{{"firstName", 1}, {"lastName", -1}}} + name, err := coll.Indexes().CreateOne(context.TODO(), model) + + * - | **Search Text** + | + | `API Documentation <{+api+}/mongo#Collection.Find>`__ + | :ref:`Search Text Guide ` + + - .. io-code-block:: + :copyable: true + + .. input:: + :language: go + + // Only searches on fields covered by text indexes + cursor, err := coll.Find(context.TODO(), bson.D{{"$text", bson.D{{"$search", "arts"}}}}) + + .. output:: + :language: go + :visible: false + + [{"firstName": "Emily" , "biography": "I am involved with arts and culture in my community."} ... ] + [{"firstName": "Juan" , "biography": "I attended the School of Arts for cello performance."} ... ] diff --git a/source/whats-new.txt b/source/reference/release-notes.txt similarity index 83% rename from source/whats-new.txt rename to source/reference/release-notes.txt index 12f5354b..92f5ad6e 100644 --- a/source/whats-new.txt +++ b/source/reference/release-notes.txt @@ -1,8 +1,9 @@ .. _golang-whats-new: +.. _golang-release-notes: -========== -What's New -========== +============= +Release Notes +============= .. contents:: On this page :local: @@ -46,12 +47,8 @@ What's New in 2.2 .. important:: Breaking Change - The {+driver-short+} v2.2 release introduces the following breaking - change: - - - Drops support for {+mdb-server+} v3.6. The minimum supported {+mdb-server+} - version is now v4.0. To learn more about compatibility with {+mdb-server+} - versions, see the :ref:`Compatibility ` reference. + The {+driver-short+} v2.2 release contains breaking changes. For more + information, see :ref:`version-2.2-breaking-changes`. This release includes the following improvements and fixes: @@ -126,53 +123,13 @@ in the {+driver-short+} source code on GitHub. .. important:: Breaking Changes - The {+driver-short+} v2.0 release introduces the following breaking - changes: - - - ``mongo.Connect()`` does not accept a Context parameter. This - method accepts only an options object. To view an example that uses - this method, see the :ref:`Connection Example Code - ` in the Connection Guide. - - - The ``Cursor.SetMaxTime()`` method is renamed to - ``Cursor.SetMaxAwaitTime()``. This method specifies the maximum time - that the server waits for new documents retrieved from a capped - collection with a tailable cursor. - - - Removal of operation-specific timeout options. The following fields - and setter methods have been removed from the driver: - - - ``AggregateOptions.MaxTime``, ``AggregateOptions.SetMaxTime()`` - - ``ClientOptions.SocketTimeout``, ``ClientOptions.SetSocketTimeout()`` - - ``CountOptions.MaxTime``, ``CountOptions.SetMaxTime()`` - - ``DistinctOptions.MaxTime``, ``DistinctOptions.SetMaxTime()`` - - ``EstimatedDocumentCountOptions.MaxTime``, ``EstimatedDocumentCountOptions.SetMaxTime()`` - - ``FindOptions.MaxTime``, ``FindOptions.SetMaxTime()`` - - ``FindOneOptions.MaxTime``, ``FindOneOptions.SetMaxTime()`` - - ``FindOneAndReplaceOptions.MaxTime``, ``FindOneAndReplaceOptions.SetMaxTime()`` - - ``FindOneAndUpdateOptions.MaxTime``, ``FindOneAndUpdateOptions.SetMaxTime()`` - - ``GridFSFindOptions.MaxTime``, ``GridFSFindOptions.SetMaxTime()`` - - ``CreateIndexesOptions.MaxTime``, ``CreateIndexesOptions.SetMaxTime()`` - - ``DropIndexesOptions.MaxTime``, ``DropIndexesOptions.SetMaxTime()`` - - ``ListIndexesOptions.MaxTime``, ``ListIndexesOptions.SetMaxTime()`` - - ``SessionOptions.DefaultMaxCommitTime``, ``SessionOptions.SetDefaultMaxCommitTime()`` - - ``TransactionOptions.MaxCommitTime``, ``TransactionOptions.SetMaxCommitTime()`` - - ``WriteConcern.WTimeout`` - - Instead, you can set a timeout on your client or within a Context. - Learn more in the :ref:`golang-timeout-setting` section of the - Connection Options guide. - - - Removal of the ``bson/primitive`` package. This package is now merged with - the ``bson`` package. To update your code, remove any ``bson/primitive`` - import statements and change any instance of ``primitive.ObjectID`` to - ``bson.ObjectId``. + The {+driver-short+} v2.0 release contains breaking changes. For more + information, see :ref:`version-2.0-breaking-changes`. This release includes the following improvements and fixes: -- Support for OpenID Connect (OIDC) authentication. To learn more, see - the :ref:`golang-mongodb-oidc` section of the Enterprise - Authentication Mechanisms guide. +- Documentation support for OpenID Connect (OIDC) authentication. To learn more, see + the :ref:`golang-mongodb-oidc` guide. - You can access the GridFS API from the ``mongo`` package. In previous versions, you could access GridFS functions from the separate ``gridfs`` @@ -259,8 +216,7 @@ The 1.17 {+driver-short+} release includes the following improvements and fixes: - Adds support for OpenID Connect (OIDC) authentication. To learn more, see - the :ref:`golang-mongodb-oidc` section of the Enterprise - Authentication Mechanisms guide. + the :ref:`golang-mongodb-oidc` guide. - Adds support for Queryable Encryption (QE) range queries. To use this feature, your app must connect to {+mdb-server+} 8.0 or later. For @@ -416,7 +372,7 @@ Logging Interface You can now record connection management and command execution events by using the ``LogSink`` logging interface. -To learn more, see the :ref:`golang-logging` Fundamentals guide. +To learn more, see the :ref:`golang-logging` guide. Additional BSON Marshalling Options ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/source/reference/upgrade.txt b/source/reference/upgrade.txt new file mode 100644 index 00000000..5f1d27e7 --- /dev/null +++ b/source/reference/upgrade.txt @@ -0,0 +1,106 @@ +.. _golang-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+} + version your application connects to and the Go version your application runs + on. For more information, see the :ref:`Compatibility ` + page. + +- Address any breaking changes between the driver versions your application uses + and your planned upgrade version in the :ref:`Breaking Changes + ` section. + +.. tip:: + + To minimize the number of changes your application requires when + upgrading driver versions in the future, use the :ref:`{+stable-api+} `. + +.. _golang-breaking-changes: + +Breaking Changes +---------------- + +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. + +.. _version-2.2-breaking-changes: + +Version 2.2 Breaking Changes +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +- Drops support for {+mdb-server+} v3.6. The minimum supported {+mdb-server+} + version is now v4.0. This also drops support for the ``MONGODB-CR`` authentication + mechanism. To learn more about compatibility with {+mdb-server+} + versions, see the :ref:`Compatibility ` reference. + +.. _version-2.0-breaking-changes: + +Version 2.0 Breaking Changes +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +- ``mongo.Connect()`` does not accept a Context parameter. This + method accepts only an options object. To view an example that uses this + method, see the :ref:`Connection Example Code ` + in the Connection Guide. + +- The ``Cursor.SetMaxTime()`` method is renamed to + ``Cursor.SetMaxAwaitTime()``. This method specifies the maximum time + that the server waits for new documents retrieved from a capped + collection with a tailable cursor. + +- Removal of operation-specific timeout options. The following fields + and setter methods have been removed from the driver: + + - ``AggregateOptions.MaxTime``, ``AggregateOptions.SetMaxTime()`` + - ``ClientOptions.SocketTimeout``, ``ClientOptions.SetSocketTimeout()`` + - ``CountOptions.MaxTime``, ``CountOptions.SetMaxTime()`` + - ``DistinctOptions.MaxTime``, ``DistinctOptions.SetMaxTime()`` + - ``EstimatedDocumentCountOptions.MaxTime``, ``EstimatedDocumentCountOptions.SetMaxTime()`` + - ``FindOptions.MaxTime``, ``FindOptions.SetMaxTime()`` + - ``FindOneOptions.MaxTime``, ``FindOneOptions.SetMaxTime()`` + - ``FindOneAndReplaceOptions.MaxTime``, ``FindOneAndReplaceOptions.SetMaxTime()`` + - ``FindOneAndUpdateOptions.MaxTime``, ``FindOneAndUpdateOptions.SetMaxTime()`` + - ``GridFSFindOptions.MaxTime``, ``GridFSFindOptions.SetMaxTime()`` + - ``CreateIndexesOptions.MaxTime``, ``CreateIndexesOptions.SetMaxTime()`` + - ``DropIndexesOptions.MaxTime``, ``DropIndexesOptions.SetMaxTime()`` + - ``ListIndexesOptions.MaxTime``, ``ListIndexesOptions.SetMaxTime()`` + - ``SessionOptions.DefaultMaxCommitTime``, ``SessionOptions.SetDefaultMaxCommitTime()`` + - ``TransactionOptions.MaxCommitTime``, ``TransactionOptions.SetMaxCommitTime()`` + - ``WriteConcern.WTimeout`` + + Instead, you can set a timeout on your client or within a Context. + Learn more in the :ref:`golang-csot` guide. + +- Removal of the ``bson/primitive`` package. This package is now merged with + the ``bson`` package. To update your code, remove any ``bson/primitive`` + import statements and change any instance of ``primitive.ObjectID`` to + ``bson.ObjectId``. \ No newline at end of file diff --git a/source/fundamentals/run-command.txt b/source/run-command.txt similarity index 100% rename from source/fundamentals/run-command.txt rename to source/run-command.txt diff --git a/source/security.txt b/source/security.txt new file mode 100644 index 00000000..efa60261 --- /dev/null +++ b/source/security.txt @@ -0,0 +1,37 @@ +.. _golang-security: + +================ +Secure Your Data +================ + +.. contents:: On this page + :local: + :backlinks: none + :depth: 2 + :class: singlecol + +.. facet:: + :name: genre + :values: reference + +.. meta:: + :keywords: ldap, encryption, principal, tls, authorize, boto, ecs, aws + :description: Learn how to use {+driver-short+} to secure your data. + +.. toctree:: + :titlesonly: + :maxdepth: 1 + + Authentication + In-Use Encryption + TLS Security Protocol + +Overview +-------- + +Learn how to set up security and authentication for your application +in the following sections: + +- :ref:`Authentication ` +- :ref:`In-Use Encryption ` +- :ref:`TLS Security Protocol ` diff --git a/source/security/authentication.txt b/source/security/authentication.txt new file mode 100644 index 00000000..08b310b0 --- /dev/null +++ b/source/security/authentication.txt @@ -0,0 +1,74 @@ +.. _golang-enterprise-authentication-mechanisms: +.. _golang-authentication-mechanisms: +.. _golang-authentication: + +========================= +Authentication Mechanisms +========================= + +.. meta:: + :description: Authenticate using the MongoDB Go Driver with various supported authentication mechanisms. + +.. default-domain:: mongodb + +.. toctree:: + + SCRAM + X.509 + AWS IAM + OIDC + LDAP (PLAIN) + Kerberos (GSSAPI) + +Overview +-------- + +In this guide, you can learn how to authenticate to MongoDB by using the +**authentication mechanisms** available in {+mdb-server+}. +Authentication mechanisms are processes by which the driver and server confirm +the identity of a client to ensure security before connecting. + +.. tip:: Connecting to MongoDB + + To learn how to establish a connection to your MongoDB deployment, see the + :ref:`golang-connect` guide. + +MongoDB Edition Compatibility +----------------------------- + +The following table lists the authentication mechanisms supported by MongoDB and +the {+mdb-server+} editions that each mechanism is compatible with. Click the name of +a mechanism to learn more about how to use it with your application. + +.. list-table:: + :header-rows: 1 + :stub-columns: 1 + + * - Authentication Mechanism + - Atlas + - Enterprise Advanced + - Community + * - :ref:`` + - Yes + - Yes + - Yes + * - :ref:`` + - Yes + - Yes + - Yes + * - :ref:`` + - Yes + - No + - No + * - :ref:`` + - Yes + - Yes + - No + * - :ref:`` + - Yes + - Yes + - No + * - :ref:`` + - No + - Yes + - No diff --git a/source/security/authentication/aws-iam.txt b/source/security/authentication/aws-iam.txt new file mode 100644 index 00000000..76256b20 --- /dev/null +++ b/source/security/authentication/aws-iam.txt @@ -0,0 +1,149 @@ +.. _golang-mongodb-aws: +.. _golang-authentication-aws: + +================================ +AWS IAM Authentication Mechanism +================================ + +.. contents:: On this page + :local: + :backlinks: none + :depth: 3 + :class: singlecol + +.. facet:: + :name: genre + :values: reference + +.. meta:: + :keywords: atlas, amazon web services, code example + +Overview +-------- + +The ``MONGODB-AWS`` authentication mechanism uses Amazon Web Services +Identity and Access Management (AWS IAM) credentials to authenticate a user to MongoDB. +You can use this mechanism only when authenticating to MongoDB Atlas. + +.. tip:: Configure Atlas for AWS IAM Authentication + + To learn more about configuring MongoDB Atlas for AWS IAM authentication, see + :atlas:`Set Up Authentication with AWS IAM ` in + the Atlas documentation. + +Specify MONGODB-AWS Authentication +---------------------------------- + +To connect to a MongoDB instance with ``MONGODB-AWS`` authentication enabled, +specify the ``MONGODB-AWS`` authentication mechanism. + +The driver checks for your credentials in the following sources in the +order listed: + +1. Connection string. +#. Environment variables. +#. Web identity token file. +#. AWS ECS endpoint specified in the + ``AWS_CONTAINER_CREDENTIALS_RELATIVE_URI`` environment variable. +#. AWS EC2 endpoint. To learn more, see `IAM Roles for Tasks + `__ + in the AWS documentation. + +.. important:: + + The driver obtains the credentials only from the first source in which they are found. + For example, if you specify your AWS credentials in the connection string, the + driver ignores any credentials that you specify in environment variables. + +.. tabs:: + + .. tab:: Connection String + :tabid: connection string + + .. tip:: + + The following examples set the appropriate credentials by using the ``SetAuth()`` + method. You can also specify these credentials by using the ``ApplyURI()`` + method. If you use the ``ApplyURI()`` method you must URL encode the username + and password to ensure they are correctly parsed. + + To connect to your MongoDB instance using your AWS IAM credentials, perform the + following steps: + + - Assign the ``AuthMechanism`` option the value ``MONGODB-AWS`` + - Assign the ``Username`` option the value of your ``accessKeyID`` + - Assign the ``Password`` option the value of your ``secretAccessKey`` + + .. literalinclude:: /includes/fundamentals/code-snippets/authentication/aws-connection-string.go + :language: go + + If you must specify an AWS session token, use the temporary + credentials returned from an `assume role request `__. + + To use temporary credentials, assign the value of your ``sessionToken`` to + the ``AuthMechanismProperties`` option: + + .. literalinclude:: /includes/fundamentals/code-snippets/authentication/aws-connection-string-session-token.go + :language: go + + .. tab:: Environment Variables + :tabid: environment variables + + To authenticate to your MongoDB instance using AWS credentials stored in + environment variables, use a shell to set the variables as follows: + + .. code-block:: bash + + export AWS_ACCESS_KEY_ID= + export AWS_SECRET_ACCESS_KEY= + export AWS_SESSION_TOKEN= + + .. note:: + + If you don't require an AWS session token for the role you're + authenticating with, omit the line containing ``AWS_SESSION_TOKEN``. + + After you've set the preceding environment variables, specify the ``MONGODB-AWS`` + authentication mechanism as shown in the following example: + + .. literalinclude:: /includes/fundamentals/code-snippets/authentication/aws-environment-variables.go + :language: go + + .. tab:: Web Identity Token File + :tabid: web-identity-token-file + + You can use the OpenID Connect (OIDC) token obtained from a web + identity provider to authenticate to Amazon Elastic Kubernetes + Service (EKS) or other services. To use an OIDC token, create or + locate the file that contains your token. Then, set the following + environment variables: + + - ``AWS_WEB_IDENTITY_TOKEN_FILE``: Set to the absolute path of the + file that contains your OIDC token. + + - ``AWS_ROLE_ARN``: Set to the IAM role used to connect to your + cluster. For example: ``arn:aws:iam::111122223333:role/my-role``. + + The following shell command sets these environment variables: + + .. code-block:: bash + + export AWS_WEB_IDENTITY_TOKEN_FILE= + export AWS_ROLE_ARN= + + After you set the preceding environment variables, specify the ``MONGODB-AWS`` + authentication mechanism as shown in the following example: + + .. literalinclude:: /includes/fundamentals/code-snippets/authentication/aws-environment-variables.go + :language: go + +API Documentation +----------------- + +To learn more about any of the methods or types discussed on this +page, see the following API documentation: + +- `Client <{+api+}/mongo#Client>`__ +- `Credential <{+api+}/mongo/options#Credential>`__ +- `SetAuth() <{+api+}/mongo/options#ClientOptions.SetAuth>`__ +- `ClientOptions <{+api+}/mongo/options#ClientOptions>`__ diff --git a/source/security/authentication/kerberos.txt b/source/security/authentication/kerberos.txt new file mode 100644 index 00000000..8c3a8718 --- /dev/null +++ b/source/security/authentication/kerberos.txt @@ -0,0 +1,128 @@ +.. _golang-kerberos: +.. _golang-authentication-kerberos: + +========================================== +Kerberos (GSSAPI) Authentication Mechanism +========================================== + +.. contents:: On this page + :local: + :backlinks: none + :depth: 2 + :class: singlecol + +.. facet:: + :name: genre + :values: reference + +.. meta:: + :keywords: code example + +Overview +-------- + +The Generic Security Services API (GSSAPI) authentication mechanism allows you to +use your principal name to authenticate to a Kerberos service. +You can use this mechanism only when authenticating to MongoDB Enterprise Advanced. + +Code Placeholders +~~~~~~~~~~~~~~~~~ + +The code examples on this page use the following placeholders: + +- ``kerberos_principal``: Your Kerberos principal. A sample username is ``myuser@KERBEROS.EXAMPLE.COM``. +- ``password``: Your Kerberos user's password. You can also store your + password in a ``keytab`` file to avoid exposing your + password in your code. +- ``connection_uri``: Your connection string URI. + +Specify Kerberos (GSSAPI) Authentication +---------------------------------------- + +You must use the ``gssapi`` `build tag `__ +and specify `cgo support `__ during +compilation to use Kerberos authentication. ``cgo`` support is enabled by +default unless you previously set environment variables to +cross-compile to a different platform. To use the ``gssapi`` build tag, +compile your code with the following command: + +.. code-block:: sh + + go build -tags gssapi + +The following code shows how you can define a ``Credential`` struct to +authenticate to Kerberos and create a client with your authentication +preferences: + +.. code-block:: go + + credential := options.Credential{ + AuthMechanism: "GSSAPI", + Username: "", + Password: "", + PasswordSet: true, + } + + uri := "" + clientOpts := options.Client().ApplyURI(uri).SetAuth(credential) + + client, err := mongo.Connect(clientOpts) + +You can omit a password or the ``PasswordSet`` field in +your ``Credential`` struct if you store authentication keys in +``keytab`` files. You can initialize a credential cache for +authenticating the Kerberos principal using the ``kinit`` binary. To +learn more about the ``kinit`` binary, see the `Oracle documentation +`__. + +The following command shows how you can invoke a credential cache for a +sample username: + +.. code-block:: sh + + kinit myuser@KERBEROS.EXAMPLE.COM + +You can alternatively authenticate using a connection string URI, +specifying your :wikipedia:`URL-encoded ` Kerberos +principal, password, and ``hostname``, the network address of your +MongoDB server: + +.. code-block:: go + + uri := "mongodb://:@/?authMechanism=GSSAPI" + +Set Custom SERVICE_NAME and SERVICE_REALM Fields +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +You can specify more properties with your authentication +mechanism using the ``AuthMechanismProperties`` field in the +``Credential`` struct. The default service name for Kerberos is +"mongodb". The following code shows how you can set custom values +for the ``SERVICE_NAME`` and ``SERVICE_REALM`` fields when defining a +``Credential`` struct: + +.. code-block:: go + + credential := options.Credential{ + AuthMechanism: "GSSAPI", + Username: "", + Password: "", + AuthMechanismProperties: map[string]string{ + "SERVICE_REALM": "", + "SERVICE_NAME": "", + }, + } + +For more properties, see the +:manual:`Server manual entry on authentication properties `. + +API Documentation +----------------- + +To learn more about any of the methods or types discussed on this +page, see the following API documentation: + +- `Client <{+api+}/mongo#Client>`__ +- `Credential <{+api+}/mongo/options#Credential>`__ +- `SetAuth() <{+api+}/mongo/options#ClientOptions.SetAuth>`__ +- `ClientOptions <{+api+}/mongo/options#ClientOptions>`__ diff --git a/source/security/authentication/ldap.txt b/source/security/authentication/ldap.txt new file mode 100644 index 00000000..2a13ef26 --- /dev/null +++ b/source/security/authentication/ldap.txt @@ -0,0 +1,92 @@ +.. _golang-LDAP: +.. _golang-authentication-ldap: + +===================================== +LDAP (PLAIN) Authentication Mechanism +===================================== + +.. contents:: On this page + :local: + :backlinks: none + :depth: 2 + :class: singlecol + +.. facet:: + :name: genre + :values: reference + +.. meta:: + :keywords: code example + +Overview +-------- + +The ``PLAIN`` authentication mechanism allows you to use your Lightweight Directory +Access Protocol (LDAP) username and password to authenticate to MongoDB. LDAP +authentication uses the PLAIN Simple Authentication and Security Layer (SASL) +defined in `RFC-4616 `__. + +You can use this mechanism only when authenticating to MongoDB Atlas or MongoDB +Enterprise Advanced. + +Code Placeholders +~~~~~~~~~~~~~~~~~ + +The code examples on this page use the following placeholders: + +- ``ldap_username``: Your LDAP username +- ``password``: Your LDAP password +- ``connection_uri``: Your connection string URI + +Specify LDAP Authentication +--------------------------- + +You can authenticate to a Lightweight Directory Access Protocol (LDAP) server +using your directory server username and password. + +.. warning:: + + This authentication mechanism sends the password to the server in + plaintext, so use this mechanism only with TLS connections. + +The following code shows how you can define a ``Credential`` struct to +authenticate to LDAP and create a client with your authentication +preferences: + +.. code-block:: go + + credential := options.Credential{ + AuthMechanism: "PLAIN", + Username: "", + Password: "", + } + + uri := "" + clientOpts := options.Client().ApplyURI(uri).SetAuth(credential) + + client, err := mongo.Connect(clientOpts) + +You can alternatively authenticate using a connection string URI, +specifying your LDAP username, password, and ``hostname``, the network +address of your MongoDB server: + +.. code-block:: go + + uri := "mongodb://:@/?authMechanism=PLAIN" + +.. note:: + + The method refers to PLAIN instead of LDAP since it + authenticates using the PLAIN Simple Authentication and Security Layer + (SASL) defined in `RFC-4616 `__. + +API Documentation +----------------- + +To learn more about any of the methods or types discussed on this +page, see the following API documentation: + +- `Client <{+api+}/mongo#Client>`__ +- `Credential <{+api+}/mongo/options#Credential>`__ +- `SetAuth() <{+api+}/mongo/options#ClientOptions.SetAuth>`__ +- `ClientOptions <{+api+}/mongo/options#ClientOptions>`__ diff --git a/source/security/authentication/oidc.txt b/source/security/authentication/oidc.txt new file mode 100644 index 00000000..dcc566ad --- /dev/null +++ b/source/security/authentication/oidc.txt @@ -0,0 +1,386 @@ +.. _golang-mongodb-oidc: +.. _golang-authentication-oidc: + +============================= +OIDC Authentication Mechanism +============================= + +.. contents:: On this page + :local: + :backlinks: none + :depth: 2 + :class: singlecol + +.. facet:: + :name: genre + :values: reference + +.. meta:: + :keywords: oidc, encryption, tls + :description: Explore sample code for connecting to MongoDB using the enterprise authentication mechanism MONGODB-OIDC with the MongoDB Go Driver. + +Overview +-------- + +.. important:: + + The MONGODB-OIDC authentication mechanism requires {+mdb-server+} + v7.0 or later running on a Linux platform. + +The {+driver-short+} supports OpenID Connect (**OIDC**) authentication for **workload +identities**. A workload identity is an identity you assign to a +software workload, such as an application, service, script, or +container, to authenticate and access other services and resources. + +The following sections describe how to use the MONGODB-OIDC +authentication mechanism to authenticate to various platforms. + +To learn more about the MONGODB-OIDC authentication mechanism, see +:manual:`OpenID Connect Authentication ` and +:manual:`MongoDB Server Parameters ` +in the {+mdb-server+} manual. + +.. _golang-mongodb-oidc-azure-imds: + +Azure IMDS +~~~~~~~~~~ + +If your application runs on an Azure VM, or otherwise uses the +`Azure Instance Metadata Service `__ +(IMDS), you can authenticate to MongoDB by using the {+driver-short+}'s +built-in Azure support. + +You can configure OIDC for Azure IMDS in the following ways: + +- Create a ``Credential`` struct and pass it to the + ``SetAuth()`` method when you create a client +- Set parameters in your connection string + +.. include:: /includes/authentication/auth-properties-commas.rst + +.. tabs:: + + .. tab:: Credential + :tabid: credential struct + + First, create a map to store your authentication + mechanism properties, as shown in the following example. Replace + the ```` placeholder with the value of the ``audience`` + parameter configured on your MongoDB deployment. + + .. code-block:: go + + props := map[string]string{ + "ENVIRONMENT": "azure", + "TOKEN_RESOURCE": "", + } + + Then, set the following ``Credential`` struct fields: + + - ``Username``: If you're using an Azure managed identity, set this to the client ID + of the managed identity. If you're using a service principal to represent an + enterprise application, set this to the application ID of the service principal. + - ``AuthMechanism``: Set to ``"MONGODB-OIDC"``. + - ``AuthMechanismProperties``: Set to the ``props`` map that you + previously created. + + The following code example shows how to set these options when creating a + ``Client``: + + .. literalinclude:: /includes/authentication/azure-imds-client.go + :dedent: + :language: go + :copyable: true + :start-after: start-azure-imds-client + :end-before: end-azure-imds-client + :emphasize-lines: 9-11 + + .. tab:: Connection String + :tabid: connectionstring + + Include the following connection options in your connection string: + + - ``username``: If you're using an Azure managed identity, set this to the client ID + of the managed identity. If you're using a service principal to represent an + enterprise application, set this to the application ID of the service principal. + - ``authMechanism``: Set to ``MONGODB-OIDC``. + - ``authMechanismProperties``: Set to + ``ENVIRONMENT:azure,TOKEN_RESOURCE:``. + Replace the ```` placeholder with the + value of the ``audience`` parameter configured on your MongoDB deployment. + + The following code example shows how to set these options in + your connection string: + + .. code-block:: go + + uri := "mongodb://:/?" + + "username=" + + "&authMechanism=MONGODB-OIDC" + + "&authMechanismProperties=ENVIRONMENT:azure,TOKEN_RESOURCE:" + + client, err := mongo.Connect(options.Client().ApplyURI(uri)) + if err != nil { + panic(err) + } + +.. tip:: + + If your application is running on an Azure VM, and only one managed identity is + associated with the VM, you can omit the ``username`` connection option. + +.. _golang-mongodb-oidc-gcp-imds: + +GCP IMDS +~~~~~~~~ + +If your application runs on a Google Compute Engine VM, or otherwise uses the +`GCP Instance Metadata Service `__, +you can authenticate to MongoDB by using the {+driver-short+}'s built-in GCP +support. + +You can configure OIDC for GCP IMDS in the following ways: + +- Create a ``Credential`` struct and pass it to the + ``SetAuth()`` method when you create a client +- Set parameters in your connection string + +.. include:: /includes/authentication/auth-properties-commas.rst + +.. tabs:: + + .. tab:: Credential + :tabid: credential struct + + First, create a map to store your authentication + mechanism properties, as shown in the following example. Replace + the ```` placeholder with the value of the ``audience`` + parameter configured on your MongoDB deployment. + + .. code-block:: go + + props := map[string]string{ + "ENVIRONMENT": "gcp", + "TOKEN_RESOURCE": "", + } + + Then, set the following ``Credential`` struct fields: + + - ``AuthMechanism``: Set to ``"MONGODB-OIDC"``. + - ``AuthMechanismProperties``: Set to the ``props`` map that you + previously created. + + The following code example shows how to set these options when creating a + ``Client``: + + .. literalinclude:: /includes/authentication/gcp-imds-client.go + :language: go + :dedent: + :copyable: true + :start-after: start-gcp-imds-client + :end-before: end-gcp-imds-client + :emphasize-lines: 9-10 + + .. tab:: Connection String + :tabid: connectionstring + + Include the following connection options in your connection string: + + - ``authMechanism``: Set to ``MONGODB-OIDC``. + - ``authMechanismProperties``: Set to + ``ENVIRONMENT:gcp,TOKEN_RESOURCE:``. + Replace the ```` placeholder with the + value of the ``audience`` parameter configured on your MongoDB deployment. + + The following code example shows how to set these options in your connection string: + + .. code-block:: go + + uri := "mongodb://:/?" + + "&authMechanism=MONGODB-OIDC" + + "&authMechanismProperties=ENVIRONMENT:gcp,TOKEN_RESOURCE:" + + client, err := mongo.Connect(options.Client().ApplyURI(uri)) + if err != nil { + panic(err) + } + +.. _golang-mongodb-oidc-custom-callback: + +Custom Callback +~~~~~~~~~~~~~~~ + +The {+driver-short+} doesn't offer built-in support for all platforms, +including the AWS Elastic Kubernetes Service (EKS). To authenticate +against unsupported platforms, you must define a custom callback +function to use OIDC to authenticate. In the driver, you can define an +``options.OIDCCallback`` function and set it as the value of the +``OIDCMachineCallback`` struct field in your ``Credential`` struct. + +The following example defines a custom callback for an EKS +cluster with a configured IAM OIDC provider. The access token is +read from a path set in the ``AWS_WEB_IDENTITY_TOKEN_FILE`` +environment variable: + +.. literalinclude:: /includes/authentication/eks-custom-callback.go + :language: go + :dedent: + :copyable: true + :start-after: start-custom-callback + :end-before: end-custom-callback + +Then, you can create a ``Credential`` struct that uses the EKS callback +function that you defined: + +.. literalinclude:: /includes/authentication/eks-custom-callback.go + :language: go + :dedent: + :copyable: true + :start-after: start-credential-callback + :end-before: end-credential-callback + :emphasize-lines: 6 + +.. _golang-mongodb-oidc-azure-envs: + +Other Azure Environments +~~~~~~~~~~~~~~~~~~~~~~~~ + +If your application runs on Azure Functions, App Service Environment (ASE), or Azure +Kubernetes Service (AKS), you can use the `azidentity +`__ +module to fetch authentication credentials. + +First, install the ``azidentity`` module by running the +following command: + +.. code-block:: sh + + go get -u github.com/Azure/azure-sdk-for-go/sdk/azidentity + +Your ``OIDCCallback`` function must return an ``OIDCCredential`` +instance that uses the ``AccessToken`` generated from the ``azidentity`` +package. See the preceding :ref:`golang-mongodb-oidc-custom-callback` +section for an example that implements a custom callback to retrieve an +access token and then creates a ``Credential``. + +.. _golang-mongodb-oidc-gcp-gke: + +GCP GKE +~~~~~~~ + +If your application runs on a GCP Google Kubernetes Engine (GKE) cluster with a +`configured service account +`__, +you can read the OIDC token from the standard service-account token-file location. + +First, define the ``OIDCCallback`` function. This function reads the +OIDC token and returns an ``OIDCCredential`` instance. + +The following example defines a callback function named ``gkeCallback``. +The function retrieves an OIDC token from a file in the standard +service-account token-file location: + +.. literalinclude:: /includes/authentication/gke-callback.go + :language: go + :copyable: true + :dedent: + :start-after: start-callback + :end-before: end-callback + +Then, you can create a ``Credential`` struct that uses the the GKE +callback function that you defined: + +.. literalinclude:: /includes/authentication/gke-callback.go + :language: go + :copyable: true + :dedent: + :start-after: start-credential-callback + :end-before: end-credential-callback + :emphasize-lines: 6 + +.. _golang-kubernetes-oidc: + +Kubernetes +~~~~~~~~~~ + +If your application runs on a Kubernetes cluster with a configured service account, +you can authenticate to MongoDB by using the {+driver-short+}'s built-in Kubernetes +support. To learn more about how to configure a service account, see the +`Managing Service Accounts `__ +guide in the Kubernetes documentation. + +You can configure OIDC for Kubernetes in the following ways: + +- Create a ``Credential`` struct and pass it to the + ``SetAuth()`` method when you create a client +- Set parameters in your connection string + +.. include:: /includes/authentication/auth-properties-commas.rst + +.. tabs:: + + .. tab:: Credential + :tabid: credential struct + + First, create a map to store your authentication + mechanism properties, as shown in the following example: + + .. code-block:: go + + props := map[string]string{ + "ENVIRONMENT": "k8s", + } + + Then, set the following ``Credential`` struct fields: + + - ``AuthMechanism``: Set to ``"MONGODB-OIDC"``. + - ``AuthMechanismProperties``: Set to the ``props`` map that you + previously created. + + The following code example shows how to set these options when creating a + ``Client``: + + .. literalinclude:: /includes/authentication/kubernetes.go + :language: go + :dedent: + :copyable: true + :start-after: start-kubernetes + :end-before: end-kubernetes + + .. tab:: Connection String + :tabid: connectionstring + + Include the following connection options in your connection string: + + - ``authMechanism``: Set to ``MONGODB-OIDC``. + - ``authMechanismProperties``: Set to ``ENVIRONMENT:k8s``. + + The following code example shows how to set these options in your connection string: + + .. code-block:: go + + uri := "mongodb://:/?" + + "&authMechanism=MONGODB-OIDC" + + "&authMechanismProperties=ENVIRONMENT:k8s" + + client, err := mongo.Connect(options.Client().ApplyURI(uri)) + if err != nil { + panic(err) + } + +Additional Information +---------------------- + +To learn more about the concepts in this guide, see the following documentation: + +- :manual:`MongoDB Server Support for Kerberos Authentication ` +- :manual:`MongoDB Server Support for LDAP Proxy Authentication ` +- :atlas:`Authentication and Authorization with OIDC/OAuth 2.0 ` + +API Documentation +~~~~~~~~~~~~~~~~~ + +- `Credential <{+api+}/mongo/options#Credential>`__ type +- `SetAuth() <{+api+}/mongo/options#ClientOptions.SetAuth>`__ method +- `OIDCCredential <{+api+}/mongo/options#OIDCCredential>`__ type +- `OIDCCallback <{+api+}/mongo/options#OIDCCallback>`__ function diff --git a/source/security/authentication/scram.txt b/source/security/authentication/scram.txt new file mode 100644 index 00000000..53ca87a9 --- /dev/null +++ b/source/security/authentication/scram.txt @@ -0,0 +1,106 @@ +.. _golang_sha_256: +.. _golang-authentication-scram: + +============================== +SCRAM Authentication Mechanism +============================== + +.. contents:: On this page + :local: + :backlinks: none + :depth: 2 + :class: singlecol + +.. facet:: + :name: genre + :values: reference + +.. meta:: + :keywords: salt, default, code example + +Overview +-------- + +**Salted Challenge Response Authentication Mechanism (SCRAM)** is a family of +authentication mechanisms that use a challenge-response mechanism to authenticate +the user. SCRAM-SHA-256, which uses the SHA-256 algorithm to hash your password, is the +default authentication mechanism. + +You can use SCRAM to authenticate to MongoDB Atlas, MongoDB +Enterprise Advanced, and MongoDB Community Edition. + +.. tip:: SCRAM Mechanisms + + To learn more about the SCRAM family of authentication mechanisms, see + `RFC 5802 `__ and + :wikipedia:`Salted Challenge Response Authentication Mechanism ` + on Wikipedia. + + For more information about the MongoDB implementation of SCRAM, see + :manual:`SCRAM ` in the {+mdb-server+} manual. + +Code Placeholders +~~~~~~~~~~~~~~~~~ + +Each authentication mechanism contains the following placeholders: + +* ``db_username`` - Your MongoDB database username +* ``db_password`` - Your MongoDB database user's password +* ``hostname`` - Your MongoDB servers network address, accessible by + your client +* ``port`` - Your MongoDB servers port number +* ``authenticationDb`` - Your MongoDB database that contains the user's + authentication data. If you omit this option, the driver uses the + default value ``admin``. + +.. _golang-scram-sha-256: + +Specify SCRAM-SHA-256 Authentication +------------------------------------ + +``SCRAM-SHA-256`` is a salted challenge-response authentication mechanism +(SCRAM) that uses your database username and password, encrypted with the ``SHA-256`` +algorithm, to authenticate your user. ``SCRAM-SHA-256`` is the default authentication mechanism. + +To specify the default authentication mechanism, omit the +``AuthMechanism`` option: + +.. code-block:: go + + credential := options.Credential{ + AuthSource: "", + Username: "", + Password: "", + } + clientOpts := options.Client().ApplyURI("mongodb://:"). + SetAuth(credential) + + client, err := mongo.Connect(clientOpts) + +To explicitly specify the ``SCRAM-SHA-256`` authentication mechanism, assign the +``AuthMechanism`` option the value ``"SCRAM-SHA-256"``: + +.. code-block:: go + :emphasize-lines: 2 + + credential := options.Credential{ + AuthMechanism: "SCRAM-SHA-256", + AuthSource: "", + Username: "", + Password: "", + } + clientOpts := options.Client().ApplyURI("mongodb://:"). + SetAuth(credential) + + client, err := mongo.Connect(clientOpts) + +API Documentation +----------------- + +To learn more about any of the methods or types discussed on this +page, see the following API documentation: + +- `Client <{+api+}/mongo#Client>`__ +- `Credential <{+api+}/mongo/options#Credential>`__ +- `SetAuth() <{+api+}/mongo/options#ClientOptions.SetAuth>`__ +- `ClientOptions <{+api+}/mongo/options#ClientOptions>`__ diff --git a/source/security/authentication/x509.txt b/source/security/authentication/x509.txt new file mode 100644 index 00000000..b4b6d74f --- /dev/null +++ b/source/security/authentication/x509.txt @@ -0,0 +1,92 @@ +.. _golang-x509: +.. _golang-authentication-x509: + +============================== +X.509 Authentication Mechanism +============================== + +.. contents:: On this page + :local: + :backlinks: none + :depth: 2 + :class: singlecol + +.. facet:: + :name: genre + :values: reference + +.. meta:: + :keywords: certificate, code example + +Overview +-------- + +Overview +-------- + +In the **X.509** authentication mechanism, the server and client use the +:wikipedia:`TLS ` protocol to exchange X.509 public-key +certificates. You can use this mechanism to authenticate to MongoDB Atlas, MongoDB +Enterprise Advanced, and MongoDB Community Edition. + +.. tip:: X.509 Mechanism + + To learn how to use TLS/SSL with the {+driver-short+}, + see the :ref:`golang-tls` guide. + + For more information about X.509 certificates, see + :manual:`Use x.509 Certificates to Authenticate Clients on Self-Managed Deployments + ` in the {+mdb-server+} manual. + +Code Placeholders +~~~~~~~~~~~~~~~~~ + +The code examples on this page use the following placeholders: + +* ``hostname``: Your MongoDB servers network address, accessible by + your client +* ``port``: Your MongoDB servers port number +- ``cafile_path``: The path to your CA File for your connection string +- ``client_certificate_path``: The path to your client certificate file or the client private key file + +Specify X.509 Authentication +---------------------------- + +To specify the ``X.509`` authentication mechanism, perform the +following: + +- Assign the ``tlsCAFile`` the path to its file in the connection string +- Assign the ``tlsCertificateKeyFile`` the path to its file in the connection string +- Assign the ``AuthMechanism`` option the value ``"MONGODB-X509"`` + +The following code example shows how to specify the ``X.509`` authentication mechanism: + +.. code-block:: go + :emphasize-lines: 4-5, 7 + + caFilePath := "" + certificateKeyFilePath := "" + + uri := "mongodb://:/?tlsCAFile=%s&tlsCertificateKeyFile=%s" + uri = fmt.Sprintf(uri, caFilePath, certificateKeyFilePath) + credential := options.Credential{ + AuthMechanism: "MONGODB-X509", + } + + clientOpts := options.Client().ApplyURI(uri).SetAuth(credential) + +.. TODO + To learn more about configuring your application to use + certificates and TLS/SSL options, see + :ref:`golang-tls-ssl-guide`. + +API Documentation +----------------- + +To learn more about any of the methods or types discussed on this +page, see the following API documentation: + +- `Client <{+api+}/mongo#Client>`__ +- `Credential <{+api+}/mongo/options#Credential>`__ +- `SetAuth() <{+api+}/mongo/options#ClientOptions.SetAuth>`__ +- `ClientOptions <{+api+}/mongo/options#ClientOptions>`__ diff --git a/source/fundamentals/encrypt-fields.txt b/source/security/encrypt-fields.txt similarity index 100% rename from source/fundamentals/encrypt-fields.txt rename to source/security/encrypt-fields.txt diff --git a/source/fundamentals/connections/tls.txt b/source/security/tls.txt similarity index 73% rename from source/fundamentals/connections/tls.txt rename to source/security/tls.txt index 96ca46ca..27bce705 100644 --- a/source/fundamentals/connections/tls.txt +++ b/source/security/tls.txt @@ -1,8 +1,8 @@ .. _golang-tls: -======================== -Enable and Configure TLS -======================== +========================== +Enable TLS on a Connection +========================== .. facet:: :name: genre @@ -10,7 +10,7 @@ Enable and Configure TLS .. meta:: :keywords: code example, security, connection options - :description: Learn how to secure your MongoDB connection using TLS by enabling TLS options and configuring certificates in your Go application. + :description: Learn how to secure your MongoDB connection by using TLS in your Go application. .. contents:: On this page :local: @@ -35,7 +35,7 @@ This guide includes the following sections: describes the certificates required to configure TLS - :ref:`Reference Certificates in a Client ` - provides an example of how to create a ``Config`` struct to configure your + provides an example of how to create a ``tls.Config`` struct to configure your TLS options - :ref:`Additional Information ` @@ -45,7 +45,7 @@ This guide includes the following sections: .. tip:: To learn more about TLS, see the Wikipedia entry on - :wikipedia:`Transport Layer Security `. + :wikipedia:`Transport Layer Security `. .. _golang-enable-tls: @@ -56,7 +56,7 @@ You can enable TLS on a connection to your MongoDB instance in one of the following ways: - Setting the ``tls`` option to ``true`` in your connection string -- Passing an empty ``Config`` struct to the ``SetTLSConfig()`` +- Passing an empty ``tls.Config`` struct to the ``SetTLSConfig()`` method when creating a ``ClientOptions`` instance Select from the following :guilabel:`Connection String` and @@ -86,11 +86,17 @@ Select from the following :guilabel:`Connection String` and .. note:: - If your connection string uses a DNS SRV record by including - the ``mongodb+srv`` prefix, TLS is enabled on your connection by - default. + If you use a DNS SRV record when connecting to MongoDB by specifying + the ``+srv`` modification in your connection string, you enable + TLS on your connection by default. To disable it, set the ``tls`` or ``ssl`` parameter + value to ``false`` in your connection string or ``ClientOptions`` object. + + To learn more about connection behavior when you use a DNS seedlist, + see the :manual:`SRV Connection Format ` + section in the {+mdb-server+}. -To view a full list of client options, see :ref:`golang-connection-options`. +To view a full list of client options, see the +:ref:`golang-connection-options` guides. .. _golang-configure-tls-certificates: @@ -101,7 +107,7 @@ To successfully initiate a TLS request, your application must present cryptographic certificates to prove its identity. Your application's certificates must be stored as PEM files to enable TLS when connecting. -.. important:: +.. important:: Use Valid Certificates in Production For production use, we recommend that your MongoDB deployment use valid certificates generated and signed by the same certificate authority. @@ -139,30 +145,18 @@ Reference Certificates in a Client You must reference your certificates in your ``ClientOptions`` object so that the server can validate them before the client connects. + We recommend that you set the ``TLSConfig`` field of your -``ClientOptions`` instance to a ``Config`` struct to configure your -TLS connection. ``Config`` structs are native to Go and allow you to keep +``ClientOptions`` instance to a ``tls.Config`` struct to configure your +TLS connection. ``tls.Config`` structs are native to Go and allow you to keep all your TLS options in a single reusable object. -To create a ``Config`` instance, import the ``crypto/tls`` and -``crypto/x509`` packages. Next, create a ``Config`` struct instance and -set the relevant struct fields for your configuration. - -Within your ``Config`` instance, you can set optional -fields to configure TLS on your connection. For **testing purposes**, -you can set the ``InsecureSkipVerify`` field to ``true``. - -.. warning:: - - Setting the ``InsecureSkipVerify`` field to ``true`` disables - both certificate and hostname validation. - - Specifying this option in a production environment makes - your application insecure and potentially - vulnerable to expired certificates and foreign processes posing - as valid client instances. +To create a ``tls.Config`` instance, import the ``crypto/tls`` and +``crypto/x509`` packages. Next, create a ``tls.Config`` struct instance and +set the relevant struct fields for your configuration, as shown in the +following section. -To learn more about the ``Config`` struct, see the `tls.Config API +To learn more about the ``tls.Config`` struct, see the `tls.Config API documentation `__. .. _golang-tls-config-full-example: @@ -170,7 +164,7 @@ documentation `__. Example ~~~~~~~ -This example performs the following actions to create a ``Config`` +This example performs the following actions to create a ``tls.Config`` instance and a ``Client`` instance with TLS enabled: 1. Creates variables to reference the certificate filepaths @@ -181,14 +175,34 @@ instance and a ``Client`` instance with TLS enabled: #. Loads the client certificate files by using the ``tls.LoadX509KeyPair()`` method -#. Instantiates a ``Config`` struct and sets the ``RootCAs`` and +#. Instantiates a ``tls.Config`` struct and sets the ``RootCAs`` and ``Certificates`` fields -#. Passes the ``Config`` instance to the ``SetTLSConfig()`` method to +#. Passes the ``tls.Config`` instance to the ``SetTLSConfig()`` method to set the ``TLSConfig`` field of the ``ClientOptions`` .. literalinclude:: /includes/fundamentals/code-snippets/tls.go :language: go + :start-after: start-tls + :end-before: end-tls + :dedent: + +Insecure Option +~~~~~~~~~~~~~~~ + +Within your ``tls.Config`` instance, you can set optional +fields to configure TLS on your connection. For **testing purposes**, +you can set the ``InsecureSkipVerify`` field to ``true``. + +.. warning:: + + Setting the ``InsecureSkipVerify`` field to ``true`` disables + both certificate and hostname validation. + + Specifying this option in a production environment makes + your application insecure and potentially + vulnerable to expired certificates and foreign processes posing + as valid client instances. .. _golang-tls-addtl-info: @@ -196,7 +210,7 @@ Additional Information ---------------------- To learn more about enabling TLS on a connection, see the -following Server manual documentation: +following documentation in the {+mdb-server+} manual: - :manual:`TLS/SSL (Transport Encryption) ` - :manual:`TLS/SSL Configuration for Clients `