From 7631f1c89f93c1a000d53c0801d7e3f4d280b92c Mon Sep 17 00:00:00 2001 From: Mike Woofter <108414937+mongoKart@users.noreply.github.com> Date: Fri, 20 Dec 2024 09:17:08 -0600 Subject: [PATCH] DOCSP-38064 - Arrays (#295) Co-authored-by: Jordan Smith <45415425+jordan-smith721@users.noreply.github.com> (cherry picked from commit a2a9e5deeb7af434a687dc1ff993d532c145d8e3) --- config/redirects | 3 + snooty.toml | 6 +- source/fundamentals/crud/write-operations.txt | 8 +- .../crud/write-operations/bulk-write.txt | 3 +- .../crud/write-operations/modify.txt | 536 --------------- .../crud/write-operations/replace.txt | 253 +++++++ .../crud/write-operations/update-many.txt | 128 ++++ .../write-operations/update-many/arrays.txt | 426 ++++++++++++ .../write-operations/update-many/fields.txt | 28 + .../crud/write-operations/update-one.txt | 114 ++++ .../write-operations/update-one/arrays.txt | 426 ++++++++++++ .../write-operations/update-one/fields.txt | 28 + source/includes/atlas-sample-data.rst | 28 + .../code-examples/replace-one/ReplaceOne.cs | 46 +- .../replace-one/ReplaceOneAsync.cs | 47 +- .../code-examples/update-many/UpdateMany.cs | 91 ++- .../update-many/UpdateManyArrays.cs | 618 ++++++++++++++++++ .../code-examples/update-one/UpdateOne.cs | 120 +++- .../update-one/UpdateOneArrays.cs | 616 +++++++++++++++++ .../update-one/UpdateOneAsync.cs | 16 +- source/includes/method-overloads.rst | 6 + .../includes/page-templates/update/arrays.rst | 377 +++++++++++ .../includes/page-templates/update/fields.rst | 235 +++++++ .../includes/page-templates/update/update.rst | 264 ++++++++ ...update-arrays-positional-operator-note.rst | 3 + .../allpositional-linq-code-intro.rst | 3 + .../allpositional-operator-code-intro.rst | 3 + .../filteredpositional-linq-code-intro.rst | 3 + ...filteredpositional-operator-code-intro.rst | 3 + .../positional-linq-code-intro.rst | 5 + .../positional-operator-code-intro.rst | 5 + .../allpositional-linq-code-intro.rst | 3 + .../allpositional-operator-code-intro.rst | 3 + .../filteredpositional-linq-code-intro.rst | 3 + ...filteredpositional-operator-code-intro.rst | 3 + .../update-one/positional-linq-code-intro.rst | 5 + .../positional-operator-code-intro.rst | 5 + source/quick-reference.txt | 19 +- source/upgrade/v2.txt | 6 + source/usage-examples/updateMany.txt | 4 +- source/usage-examples/updateOne.txt | 4 +- 41 files changed, 3882 insertions(+), 621 deletions(-) delete mode 100644 source/fundamentals/crud/write-operations/modify.txt create mode 100644 source/fundamentals/crud/write-operations/replace.txt create mode 100644 source/fundamentals/crud/write-operations/update-many.txt create mode 100644 source/fundamentals/crud/write-operations/update-many/arrays.txt create mode 100644 source/fundamentals/crud/write-operations/update-many/fields.txt create mode 100644 source/fundamentals/crud/write-operations/update-one.txt create mode 100644 source/fundamentals/crud/write-operations/update-one/arrays.txt create mode 100644 source/fundamentals/crud/write-operations/update-one/fields.txt create mode 100644 source/includes/atlas-sample-data.rst create mode 100644 source/includes/code-examples/update-many/UpdateManyArrays.cs create mode 100644 source/includes/code-examples/update-one/UpdateOneArrays.cs create mode 100644 source/includes/method-overloads.rst create mode 100644 source/includes/page-templates/update/arrays.rst create mode 100644 source/includes/page-templates/update/fields.rst create mode 100644 source/includes/page-templates/update/update.rst create mode 100644 source/includes/update-arrays-positional-operator-note.rst create mode 100644 source/includes/update-many/allpositional-linq-code-intro.rst create mode 100644 source/includes/update-many/allpositional-operator-code-intro.rst create mode 100644 source/includes/update-many/filteredpositional-linq-code-intro.rst create mode 100644 source/includes/update-many/filteredpositional-operator-code-intro.rst create mode 100644 source/includes/update-many/positional-linq-code-intro.rst create mode 100644 source/includes/update-many/positional-operator-code-intro.rst create mode 100644 source/includes/update-one/allpositional-linq-code-intro.rst create mode 100644 source/includes/update-one/allpositional-operator-code-intro.rst create mode 100644 source/includes/update-one/filteredpositional-linq-code-intro.rst create mode 100644 source/includes/update-one/filteredpositional-operator-code-intro.rst create mode 100644 source/includes/update-one/positional-linq-code-intro.rst create mode 100644 source/includes/update-one/positional-operator-code-intro.rst diff --git a/config/redirects b/config/redirects index 21ca6473..47218659 100644 --- a/config/redirects +++ b/config/redirects @@ -16,5 +16,8 @@ raw: ${prefix}/master -> ${base}/upcoming/ [*-master]: ${prefix}/${version}/fundamentals/class-mapping/ -> ${base}/${version}/fundamentals/serialization/class-mapping/ [*-v2.30]: ${prefix}/${version}/upgrade/v2/ -> ${base}/${version}/upgrade/ [*-v2.30]: ${prefix}/${version}/upgrade/v3/ -> ${base}/${version}/upgrade/ +[*-master]: ${prefix}/${version}/fundamentals/crud/write-operations/modify/#replace-operation -> ${base}/${version}/fundamentals/crud/write-operations/replace/ +[*-master]: ${prefix}/${version}/fundamentals/crud/write-operations/modify/ -> ${base}/${version}/fundamentals/crud/write-operations/ +[*-master] ${prefix}/${version}/fundamentals/builders/#define-an-update -> ${base}/${version}/fundamentals/crud/write-operations [v3.0-*]: ${prefix}/${version}/fundamentals/enterprise-authentication/ -> ${base}/${version}/fundamentals/authentication/ [*-v2.30]: ${prefix}/${version}/fundamentals/odata/ -> ${base}/${version}/ \ No newline at end of file diff --git a/snooty.toml b/snooty.toml index 04044663..de02167f 100644 --- a/snooty.toml +++ b/snooty.toml @@ -1,15 +1,17 @@ -name = "csharp" -title = "C#/.NET" toc_landing_pages = [ "/fundamentals/connection", "/fundamentals/crud", "/usage-examples", "/fundamentals", "/fundamentals/serialization", + "/fundamentals/crud/write-operations/update-one", + "/fundamentals/crud/write-operations/update-many", "/fundamentals/authentication", "/upgrade", "/fundamentals/database-collection" ] +name = "csharp" +title = "C#/.NET" intersphinx = [ "https://www.mongodb.com/docs/manual/objects.inv", diff --git a/source/fundamentals/crud/write-operations.txt b/source/fundamentals/crud/write-operations.txt index 3780689a..bb946729 100644 --- a/source/fundamentals/crud/write-operations.txt +++ b/source/fundamentals/crud/write-operations.txt @@ -11,11 +11,15 @@ Write Operations :caption: Write Operations Insert - Modify + Update One + Update Many + Replace Delete Bulk Write Operations - :ref:`csharp-insert-guide` -- :ref:`csharp-change-guide` +- :ref:`csharp-update-one` +- :ref:`csharp-update-many` +- :ref:`csharp-replace-documents` - :ref:`csharp-delete-guide` - :ref:`csharp-bulk-write` diff --git a/source/fundamentals/crud/write-operations/bulk-write.txt b/source/fundamentals/crud/write-operations/bulk-write.txt index 8da9b794..37346e76 100644 --- a/source/fundamentals/crud/write-operations/bulk-write.txt +++ b/source/fundamentals/crud/write-operations/bulk-write.txt @@ -559,7 +559,8 @@ Additional Information To learn how to perform individual write operations, see the following guides: -- :ref:`csharp-change-guide` +- :ref:`csharp-update-one` +- :ref:`csharp-update-many` - :ref:`csharp-insert-guide` - :ref:`csharp-delete-guide` diff --git a/source/fundamentals/crud/write-operations/modify.txt b/source/fundamentals/crud/write-operations/modify.txt deleted file mode 100644 index 7d187cd7..00000000 --- a/source/fundamentals/crud/write-operations/modify.txt +++ /dev/null @@ -1,536 +0,0 @@ -.. _csharp-change-guide: - -================ -Modify Documents -================ - -.. contents:: On this page - :local: - :backlinks: none - :depth: 2 - :class: singlecol - -.. facet:: - :name: genre - :values: reference - -.. meta:: - :keywords: update, replace, synchronous, asynchronous, bulk - -Overview --------- - -In this guide, you can learn how to use the {+driver-long+} to modify -documents in a MongoDB collection by performing the following operations: - -- :ref:`Update Operations ` -- :ref:`Replace Operations ` - -The {+driver-short+} provides the following methods to modify documents, -each of which has an asynchronous and synchronous version: - -- ``UpdateOneAsync()`` or ``UpdateOne()`` -- ``UpdateManyAsync()`` or ``UpdateMany()`` -- ``ReplaceOneAsync()`` or ``ReplaceOne()`` - -.. tip:: Interactive Lab - - This page includes a short interactive lab that demonstrates how to - modify data by using the ``UpdateManyAsync()`` method. You can complete this - lab directly in your browser window without installing MongoDB or a code editor. - - To start the lab, click the :guilabel:`Open Interactive Tutorial` button at the - top of the page. To expand the lab to a full-screen format, click the - full-screen button (:guilabel:`⛶`) in the top-right corner of the lab pane. - -Sample Data -~~~~~~~~~~~ - -The examples in this guide use the ``restaurants`` collection -from the ``sample_restaurants`` database. The documents in this -collection use the following ``Restaurant``, ``Address``, and ``GradeEntry`` -classes as models: - -.. literalinclude:: /includes/code-examples/Restaurant.cs - :language: csharp - :copyable: - :dedent: - -.. literalinclude:: /includes/code-examples/Address.cs - :language: csharp - :copyable: - :dedent: - -.. literalinclude:: /includes/code-examples/GradeEntry.cs - :language: csharp - :copyable: - :dedent: - -.. include:: /includes/convention-pack-note.rst - -This collection is from the :atlas:`sample datasets ` provided -by Atlas. See the :ref:`` to learn how to create a free MongoDB cluster -and load this sample data. - -.. _csharp-update-operation: - -Update Operations ------------------ - -You can perform update operations in MongoDB with the following methods: - -- ``UpdateOne()``, which updates *the first document* that matches the search criteria -- ``UpdateMany()``, which updates *all documents* that match the search criteria - -Required Parameters -~~~~~~~~~~~~~~~~~~~ - -Each update method requires the following parameters: - -- A **query filter** document, which determines which records to update. See the - :manual:`MongoDB server manual ` for - more information about query filters. -- An **update** document, which specifies the **update operator** (the kind of update to - perform) and the fields and values that should change. See the - :manual:`Field Update Operators Manual page` for a complete - list of update operators and their usage. - -The {+driver-short+} provides a ``Builders`` class that simplifies the creation of both -query filters and update documents. The following code sample uses ``Builders`` to create -two documents for use as parameters in an update operation: - -- A query filter that searches for restaurants with a ``cuisine`` field value of "Pizza" -- An update document that sets the value of the ``cuisine`` field of these restaurants - to "Pasta and breadsticks" - -.. literalinclude:: /includes/code-examples/update-many/UpdateMany.cs - :language: csharp - :dedent: - :start-after: // start-update-many - :end-before: // end-update-many - -.. tip:: Aggregation Pipelines in Update Operations - - If you are using MongoDB Version 4.2 or later, you can use aggregation - pipelines made up of a subset of aggregation stages in update operations. For - more information on the aggregation stages MongoDB supports in - aggregation pipelines used in update operations, see our tutorial on building - :manual:`updates with aggregation pipelines `. - -Update One Document -~~~~~~~~~~~~~~~~~~~ - -The following code shows how to use the asynchronous ``UpdateOneAsync()`` method -or the synchronous ``UpdateOne()`` method to update one document. - -.. tabs:: - - .. tab:: Asynchronous - :tabid: update-one-async - - .. code-block:: csharp - :copyable: true - - var result = await _restaurantsCollection.UpdateOneAsync(filter, update); - - .. tab:: Synchronous - :tabid: update-one-sync - - .. code-block:: csharp - :copyable: true - - var result = _restaurantsCollection.UpdateOne(filter, update); - -Update Many Documents -~~~~~~~~~~~~~~~~~~~~~ - -The following code shows how to use the asynchronous -``UpdateManyAsync()`` method or the synchronous ``UpdateMany()`` method to -update all matched documents. - -.. tabs:: - - .. tab:: Asynchronous - :tabid: update-many-async - - .. code-block:: csharp - :copyable: true - - var result = await _restaurantsCollection.UpdateManyAsync(filter, update); - - .. tab:: Synchronous - :tabid: update-many-sync - - .. code-block:: csharp - :copyable: true - - var result = _restaurantsCollection.UpdateMany(filter, update); - -.. tip:: - - Find runnable examples that use these methods under :ref:`Additional - Information `. - -Customize the Update Operation -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Both methods optionally accept an ``UpdateOptions`` object as an additional parameter, -which represents options you can use to configure the update operation. -If you don't specify any ``UpdateOptions`` properties, the driver does -not customize the update operation. - -The ``UpdateOptions`` type allows you to configure options with the -following properties: - -.. list-table:: - :widths: 30 70 - :header-rows: 1 - - * - Property - - Description - - * - ``ArrayFilters`` - - | Specifies which array elements to modify for an update operation on an array field. - See :manual:`the MongoDB server manual` - for more information. - - * - ``BypassDocumentValidation`` - - | Specifies whether the update operation bypasses document validation. This lets you - update documents that don't meet the schema validation requirements, if any - exist. See :manual:`the MongoDB server manual` - for more information on schema validation. - - * - ``Collation`` - - | Specifies the kind of language collation to use when sorting - results. See :manual:`the MongoDB server manual` - for more information on collation. - - * - ``Comment`` - - | Gets or sets the user-provided comment for the operation. - See :manual:`the MongoDB server manual` - for more information. - - * - ``Hint`` - - | Gets or sets the index to use to scan for documents. - See :manual:`the MongoDB server manual` - for more information. - - * - ``IsUpsert`` - - | Specifies whether the update operation performs an upsert operation if no - documents match the query filter. - See :manual:`the MongoDB server manual ` - for more information. - - * - ``Let`` - - | Gets or sets the let document. - See :manual:`the MongoDB server manual ` - for more information. - -Return Value -~~~~~~~~~~~~ - -The ``UpdateOne()`` and ``UpdateMany()`` methods each return an ``UpdateResult`` -object. The ``UpdateResult`` type contains the following properties: - -.. list-table:: - :widths: 30 70 - :header-rows: 1 - - * - Property - - Description - - * - ``IsAcknowledged`` - - | Indicates whether the update operation was acknowledged by MongoDB. - - * - ``IsModifiedCountAvailable`` - - | Indicates whether you can read the count of updated records on the - ``UpdateResult``. - - * - ``MatchedCount`` - - | The number of documents that matched the query filter, regardless of - how many were updated. - - * - ``ModifiedCount`` - - | The number of documents updated by the update operation. If an updated - document is identical to the original, it won't be included in this count. - - * - ``UpsertedId`` - - | The ID of the document that was upserted in the database, if the driver - performed an upsert. - -Example -~~~~~~~ - -The following code uses the ``UpdateMany()`` method to find all documents where the -``borough`` field has the value "Manhattan", then updates the ``borough`` -value in these documents to "Manhattan (north)". Because the ``IsUpsert`` option is -set to ``true``, the driver inserts a new document if the query filter doesn't -match any existing documents. - -.. io-code-block:: - :copyable: true - - .. input:: - :language: csharp - - var filter = Builders.Filter - .Eq(restaurant => restaurant.Borough, "Manhattan"); - - var update = Builders.Update - .Set(restaurant => restaurant.Borough, "Manhattan (north)"); - - UpdateOptions opts = new UpdateOptions() - { - Comment = new BsonString("Borough updated for C# Driver Fundamentals"), - IsUpsert = true - }; - - Console.WriteLine("Updating documents..."); - var result = _restaurantsCollection.UpdateMany(filter, update, opts); - - Console.WriteLine($"Updated documents: {result.ModifiedCount}"); - Console.WriteLine($"Result acknowledged? {result.IsAcknowledged}"); - - .. output:: - :language: none - :visible: false - - Updating documents... - Updated documents: 10259 - Result acknowledged? True - -.. note:: - - If the preceding example used the ``UpdateOne()`` method instead of - ``UpdateMany()``, the driver would update only the first of the - matched documents. - -.. _csharp-replace-operation: - -Replace Operation ------------------ - -You can perform a replace operation in MongoDB with the ``ReplaceOne()`` method. -This method removes all fields (except the ``_id`` field) from the first document that -matches the search criteria, then inserts the fields and values you specify into the -document. - -Required Parameters -~~~~~~~~~~~~~~~~~~~ - -The ``ReplaceOne()`` method requires the following parameters: - -- A query filter document, which determines which record to replace. -- A **replacement** document, which specifies the fields and values to insert in the new - document. If the documents in your collection are mapped to a {+language+} class, - the replacement document can be an instance of this class. - -Like in an update operation, you can use the ``Builders`` class in the {+driver-short+} -to create a query filter. -The following code sample uses ``Builders`` to create a query filter that searches -for restaurants with a ``name`` field value of "Pizza Town". The code also creates a new -``Restaurant`` object that will replace the first matched document. - -.. literalinclude:: /includes/code-examples/replace-one/ReplaceOne.cs - :language: csharp - :dedent: - :start-after: // start-replace-one - :end-before: // end-replace-one - -.. important:: - - The values of ``_id`` fields are immutable. If your replacement document specifies - a value for the ``_id`` field, it must match the ``_id`` value of the existing document. - -The following code shows how to use the asynchronous ``ReplaceOneAsync()`` method -or the synchronous ``ReplaceOne()`` method to replace one document. - -.. tabs:: - - .. tab:: Asynchronous - :tabid: replace-one-async - - .. code-block:: csharp - :copyable: true - - var result = await _restaurantsCollection.ReplaceOneAsync(filter, newRestaurant); - - .. tab:: Synchronous - :tabid: replace-one-sync - - .. code-block:: csharp - :copyable: true - - var result = _restaurantsCollection.ReplaceOne(filter, newRestaurant); - -.. tip:: - - Find runnable examples that use these methods under :ref:`Additional - Information `. - -Customize the Replace Operation -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -The ``ReplaceOne()`` method optionally accepts a ``ReplaceOptions`` object as an -additional parameter, which represents options you can use to configure the replace -operation. If you don't specify any ``ReplaceOptions`` properties, the driver does -not customize the replace operation. - -The ``ReplaceOptions`` type allows you to configure options with the -following properties: - -.. list-table:: - :widths: 30 70 - :header-rows: 1 - - * - Property - - Description - - * - ``BypassDocumentValidation`` - - | Specifies whether the replace operation bypasses document validation. This lets you - replace documents that don't meet the schema validation requirements, if any - exist. See :manual:`the MongoDB server manual` - for more information on schema validation. - - * - ``Collation`` - - | Specifies the kind of language collation to use when sorting - results. See :manual:`the MongoDB server manual` - for more information on collation. - - * - ``Comment`` - - | Gets or sets the user-provided comment for the operation. - See :manual:`the MongoDB server manual` - for more information. - - * - ``Hint`` - - | Gets or sets the index to use to scan for documents. - See :manual:`the MongoDB server manual` - for more information. - - * - ``IsUpsert`` - - | Specifies whether the replace operation performs an upsert operation if no - documents match the query filter. - See :manual:`the MongoDB server manual ` - for more information. - - * - ``Let`` - - | Gets or sets the let document. - See :manual:`the MongoDB server manual ` - for more information. - -Return Value -~~~~~~~~~~~~ - -The ``ReplaceOne()`` method returns a ``ReplaceOneResult`` -object. The ``ReplaceOneResult`` type contains the following properties: - -.. list-table:: - :widths: 30 70 - :header-rows: 1 - - * - Property - - Description - - * - ``IsAcknowledged`` - - | Indicates whether the replace operation was acknowledged by MongoDB. - - * - ``IsModifiedCountAvailable`` - - | Indicates whether you can read the count of replaced records on the - ``ReplaceOneResult``. - - * - ``MatchedCount`` - - | The number of documents that matched the query filter, regardless of - whether one was replaced. - - * - ``ModifiedCount`` - - | The number of documents replaced by the replace operation. - - * - ``UpsertedId`` - - | The ID of the document that was upserted in the database, if the driver - performed an upsert. - -Example -~~~~~~~ - -The following code uses the ``ReplaceOne()`` method to find the first document where the -``name`` field has the value "Pizza Town", then replaces this document -with a new ``Restaurant`` document named "Food World". Because the ``IsUpsert`` option is -set to ``true``, the driver inserts a new document if the query filter doesn't -match any existing documents. - -.. io-code-block:: - :copyable: true - - .. input:: - :language: csharp - - var filter = Builders.Filter.Eq(restaurant => restaurant.Name, "Pizza Town"); - - Restaurant newRestaurant = new() - { - Name = "Food World", - Cuisine = "American", - Address = new BsonDocument - { - {"street", "Food St"}, - {"zipcode", "10003"}, - }, - Borough = "Manhattan", - }; - - ReplaceOptions opts = new ReplaceOptions() - { - Comment = new BsonString("Restaurant replaced for {+driver-short+} Fundamentals"), - IsUpsert = true - }; - - Console.WriteLine("Replacing document..."); - var result = _restaurantsCollection.ReplaceOne(filter, newRestaurant, opts); - - Console.WriteLine($"Replaced documents: {result.ModifiedCount}"); - Console.WriteLine($"Result acknowledged? {result.IsAcknowledged}"); - - .. output:: - :language: none - :visible: false - - Replacing document... - Replaced documents: 1 - Result acknowledged? True - -.. _csharp-change-info: - -Additional Information ----------------------- - -For runnable examples of the update and replace operations, see the following usage -examples: - -- :ref:`csharp-update-one` -- :ref:`csharp-update-many` -- :ref:`csharp-replace-one` - -To learn more about creating query filters, see the :ref:`csharp-specify-query` guide. - -API Documentation -~~~~~~~~~~~~~~~~~ - -To learn more about any of the methods or types discussed in this -guide, see the following API documentation: - -* `UpdateOne() <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.IMongoCollection-1.UpdateOne.html>`__ -* `UpdateOneAsync() <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.IMongoCollection-1.UpdateOneAsync.html>`__ -* `UpdateMany() <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.IMongoCollection-1.UpdateMany.html>`__ -* `UpdateManyAsync() <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.IMongoCollection-1.UpdateManyAsync.html>`__ -* `UpdateOptions <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.UpdateOptions.html>`__ -* `UpdateResult <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.UpdateResult.html>`__ -* `ReplaceOne() <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.IMongoCollection-1.ReplaceOne.html>`__ -* `ReplaceOneAsync() <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.IMongoCollection-1.ReplaceOneAsync.html>`__ -* `ReplaceOptions <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.ReplaceOptions.html>`__ -* `ReplaceOneResult <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.ReplaceOneResult.html>`__ - -.. _csharp-update-instruqt-lab: - -.. instruqt:: /mongodb-docs/tracks/update-a-document---c-net-driver?token=em_69t_l-j0BC_en7Uy - :title: UpdateManyAsync() Lesson - :drawer: \ No newline at end of file diff --git a/source/fundamentals/crud/write-operations/replace.txt b/source/fundamentals/crud/write-operations/replace.txt new file mode 100644 index 00000000..e64af0d9 --- /dev/null +++ b/source/fundamentals/crud/write-operations/replace.txt @@ -0,0 +1,253 @@ +.. _csharp-replace-operation: +.. _csharp-replace-documents: + +================= +Replace Documents +================= + +.. contents:: On this page + :local: + :backlinks: none + :depth: 2 + :class: singlecol + +.. facet:: + :name: genre + :values: reference + +.. meta:: + :keywords: replace, synchronous, asynchronous + +Overview +-------- + +In this guide, you can learn how to use the {+driver-short+} to replace +documents in a MongoDB collection. + +The {+driver-short+} provides the ``ReplaceOne()`` and ``ReplaceOneAsync()`` methods. +These methods remove all fields (except the ``_id`` field) from the first document that +matches the search criteria, then insert the fields and values you specify into the +document. + +.. include:: /includes/method-overloads.rst + +.. include:: /includes/atlas-sample-data.rst + +Replace One Document +-------------------- + +To replace a document in a collection, call the ``ReplaceOne()`` or ``ReplaceOneAsync()`` +method. These methods accept the following parameters: + +.. list-table:: + :widths: 30 70 + :header-rows: 1 + + * - Parameter + - Description + + * - ``filter`` + - A *query filter* that specifies the document to replace. You can use the + ``Builders`` class to create a query filter. For more information about + query filters, see the + :manual:`{+mdb-server+} manual `. + + **Data Type:** `FilterDefinition <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.FilterDefinition-1.html>`__ + + * - ``replacement`` + - A *replacement* document, which specifies the fields and values to insert in the new + document. If the documents in your collection are mapped to a {+language+} class, + the replacement document can be an instance of this class. + + **Data Type:** ``TDocument`` + + * - ``options`` + - *Optional.* An instance of the ``ReplaceOptions`` class that specifies the + configuration for the replace operation. The default value is ``null``. + + **Data Type:** `ReplaceOptions <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.ReplaceOptions.html>`__ + + * - ``cancellationToken`` + - *Optional.* A token that you can use to cancel the operation. + + **Data type**: `CancellationToken `__ + +The following code example demonstrates how to perform a replace operation. The +code performs the following steps: + +1. Creates a query filter by using the ``Builders`` class. The filter matches all + documents where the ``cuisine`` field has the value ``"Pizza"``. +#. Creates a new ``Restaurant`` object. +#. Calls the ``ReplaceOne()`` method on the ``restaurants`` collection. This operation + finds the first matching document in the collection and replaces it with the newly created + document. + +Select the :guilabel:`Synchronous` or :guilabel:`Asynchronous` tab to see the +corresponding code. + +.. tabs:: + + .. tab:: Synchronous + :tabid: sync + + .. literalinclude:: /includes/code-examples/replace-one/ReplaceOne.cs + :language: csharp + :copyable: true + :dedent: + :start-after: // start-replace-one + :end-before: // end-replace-one + + .. tab:: Asynchronous + :tabid: async + + .. literalinclude:: /includes/code-examples/replace-one/ReplaceOneAsync.cs + :language: csharp + :copyable: true + :dedent: + :start-after: // start-replace-one-async + :end-before: // end-replace-one-async + +.. important:: + + The values of ``_id`` fields are immutable. If your replacement document specifies + a value for the ``_id`` field, it must match the ``_id`` value of the existing document. + +Customize the Replace Operation +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The ``ReplaceOne()`` and ``ReplaceOneAsync()`` methods optionally accept a +``ReplaceOptions`` object as a parameter, which represents options you can use to +configure the replace operation. + +The ``ReplaceOptions`` class contains the following properties: + +.. list-table:: + :widths: 30 70 + :header-rows: 1 + + * - Property + - Description + + * - ``BypassDocumentValidation`` + - Specifies whether the replace operation bypasses document validation. This lets you + replace documents that don't meet the schema validation requirements, if any + exist. See :manual:`the {+mdb-server+} manual ` + for more information on schema validation. + + **Data Type:** ``bool?`` + + * - ``Collation`` + - Specifies the kind of language collation to use when sorting + results. See :manual:`the {+mdb-server+} manual ` + for more information on collation. + + **Data Type:** `Collation <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.Collation.html>`__ + + * - ``Comment`` + - Gets or sets the user-provided comment for the operation. + See :manual:`the {+mdb-server+} manual` + for more information. + + **Data Type:** `BsonValue <{+new-api-root+}/MongoDB.Bson/MongoDB.Bson.BsonValue.html>`__ + + * - ``Hint`` + - Gets or sets the index to use to scan for documents. + See :manual:`the {+mdb-server+} manual` + for more information. + + **Data Type:** `BsonValue <{+new-api-root+}/MongoDB.Bson/MongoDB.Bson.BsonValue.html>`__ + + * - ``IsUpsert`` + - Specifies whether the replace operation performs an upsert operation if no + documents match the query filter. + See :manual:`the {+mdb-server+} manual ` + for more information. + + **Data Type:** ``bool`` + + * - ``Let`` + - Gets or sets the let document. + See :manual:`the {+mdb-server+} manual ` + for more information. + + **Data Type:** `BsonDocument <{+new-api-root+}/MongoDB.Bson/MongoDB.Bson.BsonDocument.html>`__ + +The following example performs the same steps as the preceding example, but also uses +the ``BypassDocumentValidation`` option to bypass any schema validation requirements. +Select the :guilabel:`Synchronous` or :guilabel:`Asynchronous` tab to see the corresponding +code. + +.. tabs:: + + .. tab:: Synchronous + :tabid: sync + + .. literalinclude:: /includes/code-examples/replace-one/ReplaceOne.cs + :language: csharp + :copyable: true + :dedent: + :start-after: // start-replace-one-sync-with-options + :end-before: // end-replace-one-sync-with-options + + .. tab:: Asynchronous + :tabid: async + + .. literalinclude:: /includes/code-examples/replace-one/ReplaceOneAsync.cs + :language: csharp + :copyable: true + :dedent: + :start-after: // start-replace-one-async-with-options + :end-before: // end-replace-one-async-with-options + +Return Value +~~~~~~~~~~~~ + +The ``ReplaceOne()`` method returns a ``ReplaceOneResult`` +object, and the ``ReplaceOneAsync()`` method returns a ``Task`` object. +The ``ReplaceOneResult`` class contains the following properties: + +.. list-table:: + :widths: 30 70 + :header-rows: 1 + + * - Property + - Description + + * - ``IsAcknowledged`` + - Indicates whether the replace operation was acknowledged by MongoDB. + + **Data Type:** ``bool`` + + * - ``IsModifiedCountAvailable`` + - Indicates whether you can read the count of replaced records on the + ``ReplaceOneResult``. + + **Data Type:** ``bool`` + + * - ``MatchedCount`` + - The number of documents that matched the query filter, regardless of + whether one was replaced. + + **Data Type:** ``long`` + + * - ``ModifiedCount`` + - The number of documents replaced by the replace operation. + + **Data Type:** ``long`` + + * - ``UpsertedId`` + - The ID of the document that was upserted in the database, if the driver + performed an upsert. + + **Data Type:** `BsonValue <{+new-api-root+}/MongoDB.Bson/MongoDB.Bson.BsonValue.html>`__ + +API Documentation +~~~~~~~~~~~~~~~~~ + +To learn more about any of the methods and classes used on this page, +see the following API documentation: + +* `ReplaceOne() <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.IMongoCollection-1.ReplaceOne.html>`__ +* `ReplaceOneAsync() <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.IMongoCollection-1.ReplaceOneAsync.html>`__ +* `ReplaceOptions <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.ReplaceOptions.html>`__ +* `ReplaceOneResult <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.ReplaceOneResult.html>`__ \ No newline at end of file diff --git a/source/fundamentals/crud/write-operations/update-many.txt b/source/fundamentals/crud/write-operations/update-many.txt new file mode 100644 index 00000000..e05203fd --- /dev/null +++ b/source/fundamentals/crud/write-operations/update-many.txt @@ -0,0 +1,128 @@ +.. _csharp-update-many: + +=========== +Update Many +=========== + +.. contents:: On this page + :local: + :backlinks: none + :depth: 2 + :class: singlecol + +.. facet:: + :name: genre + :values: reference + +.. meta:: + :keywords: synchronous, asynchronous + +.. toctree:: + :caption: Update Documents + + Fields + Arrays + +.. include:: /includes/page-templates/update/update.rst + + .. replacement:: sync-method + + ``UpdateMany()`` + + .. replacement:: async-method + + ``UpdateManyAsync()`` + + .. replacement:: document-or-documents + + documents + + .. replacement:: fields-link + + :ref:`csharp-update-many-fields` + + .. replacement:: arrays-link + + :ref:`csharp-update-many-arrays` + + .. replacement:: single-or-multiple + + multiple documents + + .. replacement:: usage-examples-link + + :ref:`csharp-examples-update-many` + + .. replacement:: sync-api-link + + `UpdateMany() <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.IMongoCollection-1.UpdateMany.html>`__ + + .. replacement:: async-api-link + + `UpdateManyAsync() <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.IMongoCollection-1.UpdateManyAsync.html>`__ + + .. replacement:: instruqt-lab-component + + .. instruqt:: /mongodb-docs/tracks/update-a-document---c-net-driver?token=em_69t_l-j0BC_en7Uy + :title: UpdateManyAsync() Lesson + :drawer: + + .. replacement:: instruqt-lab-instructions + + This page includes a short interactive lab that demonstrates how to + modify data by using the ``UpdateManyAsync()`` method. You can complete this + lab directly in your browser window without installing MongoDB or a code editor. + + To start the lab, click the :guilabel:`Open Interactive Tutorial` button at the + top of the page. To expand the lab to a full-screen format, click the + full-screen button (:guilabel:`⛶`) in the top-right corner of the lab pane. + + .. replacement:: combine-code-example-tabs + + .. tabs:: + + .. tab:: UpdateMany (Sync) + :tabid: sync + + .. literalinclude:: /includes/code-examples/update-many/UpdateMany.cs + :language: csharp + :copyable: true + :dedent: + :start-after: // start-combine-sync + :end-before: // end-combine-sync + + .. tab:: UpdateMany (Async) + :tabid: async + + .. literalinclude:: /includes/code-examples/update-many/UpdateMany.cs + :language: csharp + :copyable: true + :dedent: + :start-after: // start-combine-async + :end-before: // end-combine-async + + .. replacement:: pipeline-code-example-tabs + + .. tabs:: + + .. tab:: UpdateMany (Sync) + :tabid: sync + + .. literalinclude:: /includes/code-examples/update-many/UpdateMany.cs + :language: csharp + :copyable: true + :dedent: + :start-after: // start-pipeline-sync + :end-before: // end-pipeline-sync + + .. tab:: UpdateMany (Async) + :tabid: async + + .. literalinclude:: /includes/code-examples/update-many/UpdateMany.cs + :language: csharp + :copyable: true + :dedent: + :start-after: // start-pipeline-async + :end-before: // end-pipeline-async + + diff --git a/source/fundamentals/crud/write-operations/update-many/arrays.txt b/source/fundamentals/crud/write-operations/update-many/arrays.txt new file mode 100644 index 00000000..c3fe8399 --- /dev/null +++ b/source/fundamentals/crud/write-operations/update-many/arrays.txt @@ -0,0 +1,426 @@ +.. _csharp-update-many-arrays: + +============= +Update Arrays +============= + +.. contents:: On this page + :local: + :backlinks: none + :depth: 2 + :class: singlecol + +.. facet:: + :name: genre + :values: reference + +.. meta:: + :keywords: synchronous, asynchronous + +.. include:: /includes/page-templates/update/arrays.rst + + .. replacement:: sync-method + + ``UpdateMany()`` + + .. replacement:: async-method + + ``UpdateManyAsync()`` + + .. replacement:: matching-document-or-documents + + all matching documents + + .. replacement:: pusheach-section-ref + + .. _csharp-update-many-arrays-pusheach: + + .. replacement:: pusheach-method-link + + :ref:`PushEach() ` + + .. replacement:: update-page-link + + :ref:`` + + .. replacement:: push-code-example-tabs + + .. tabs:: + + .. tab:: Synchronous + :tabid: sync + + .. literalinclude:: /includes/code-examples/update-many/UpdateManyArrays.cs + :language: csharp + :copyable: true + :dedent: + :start-after: // start-update-many-push + :end-before: // end-update-many-push + + .. tab:: Asynchronous + :tabid: async + + .. literalinclude:: /includes/code-examples/update-many/UpdateManyArrays.cs + :language: csharp + :copyable: true + :dedent: + :start-after: // start-update-many-push-async + :end-before: // end-update-many-push-async + + .. replacement:: addtoset-code-example-tabs + + .. tabs:: + + .. tab:: Synchronous + :tabid: sync + + .. literalinclude:: /includes/code-examples/update-many/UpdateManyArrays.cs + :language: csharp + :copyable: true + :dedent: + :start-after: // start-update-many-addtoset + :end-before: // end-update-many-addtoset + + .. tab:: Asynchronous + :tabid: async + + .. literalinclude:: /includes/code-examples/update-many/UpdateManyArrays.cs + :language: csharp + :copyable: true + :dedent: + :start-after: // start-update-many-addtoset-async + :end-before: // end-update-many-addtoset-async + + .. replacement:: pusheach-code-example-tabs + + .. tabs:: + + .. tab:: Synchronous + :tabid: sync + + .. literalinclude:: /includes/code-examples/update-many/UpdateManyArrays.cs + :language: csharp + :copyable: true + :dedent: + :start-after: // start-update-many-pusheach + :end-before: // end-update-many-pusheach + + .. tab:: Asynchronous + :tabid: async + + .. literalinclude:: /includes/code-examples/update-many/UpdateManyArrays.cs + :language: csharp + :copyable: true + :dedent: + :start-after: // start-update-many-pusheach-async + :end-before: // end-update-many-pusheach-async + + .. replacement:: addtoseteach-code-example-tabs + + .. tabs:: + + .. tab:: Synchronous + :tabid: sync + + .. literalinclude:: /includes/code-examples/update-many/UpdateManyArrays.cs + :language: csharp + :copyable: true + :dedent: + :start-after: // start-update-many-addtoseteach + :end-before: // end-update-many-addtoseteach + + .. tab:: Asynchronous + :tabid: async + + .. literalinclude:: /includes/code-examples/update-many/UpdateManyArrays.cs + :language: csharp + :copyable: true + :dedent: + :start-after: // start-update-many-addtoseteach-async + :end-before: // end-update-many-addtoseteach-async + + .. replacement:: popfirst-code-example-tabs + + .. tabs:: + + .. tab:: Synchronous + :tabid: sync + + .. literalinclude:: /includes/code-examples/update-many/UpdateManyArrays.cs + :language: csharp + :copyable: true + :dedent: + :start-after: // start-update-many-popfirst + :end-before: // end-update-many-popfirst + + .. tab:: Asynchronous + :tabid: async + + .. literalinclude:: /includes/code-examples/update-many/UpdateManyArrays.cs + :language: csharp + :copyable: true + :dedent: + :start-after: // start-update-many-popfirst-async + :end-before: // end-update-many-popfirst-async + + .. replacement:: poplast-code-example-tabs + + .. tabs:: + + .. tab:: Synchronous + :tabid: sync + + .. literalinclude:: /includes/code-examples/update-many/UpdateManyArrays.cs + :language: csharp + :copyable: true + :dedent: + :start-after: // start-update-many-poplast + :end-before: // end-update-many-poplast + + .. tab:: Asynchronous + :tabid: async + + .. literalinclude:: /includes/code-examples/update-many/UpdateManyArrays.cs + :language: csharp + :copyable: true + :dedent: + :start-after: // start-update-many-poplast-async + :end-before: // end-update-many-poplast-async + + .. replacement:: pull-code-example-tabs + + .. tabs:: + + .. tab:: Synchronous + :tabid: sync + + .. literalinclude:: /includes/code-examples/update-many/UpdateManyArrays.cs + :language: csharp + :copyable: true + :dedent: + :start-after: // start-update-many-pull + :end-before: // end-update-many-pull + :emphasize-lines: 13-17 + + .. tab:: Asynchronous + :tabid: async + + .. literalinclude:: /includes/code-examples/update-many/UpdateManyArrays.cs + :language: csharp + :copyable: true + :dedent: + :start-after: // start-update-many-pull-async + :end-before: // end-update-many-pull-async + :emphasize-lines: 13-17 + + .. replacement:: pullall-code-example-tabs + + .. tabs:: + + .. tab:: Synchronous + :tabid: sync + + .. literalinclude:: /includes/code-examples/update-many/UpdateManyArrays.cs + :language: csharp + :copyable: true + :dedent: + :start-after: // start-update-many-pullall + :end-before: // end-update-many-pullall + :emphasize-lines: 15-20 + + .. tab:: Asynchronous + :tabid: async + + .. literalinclude:: /includes/code-examples/update-many/UpdateManyArrays.cs + :language: csharp + :copyable: true + :dedent: + :start-after: // start-update-many-pullall-async + :end-before: // end-update-many-pullall-async + :emphasize-lines: 15-20 + + .. replacement:: pullfilter-code-example-tabs + + .. tabs:: + + .. tab:: Synchronous + :tabid: sync + + .. literalinclude:: /includes/code-examples/update-many/UpdateManyArrays.cs + :language: csharp + :copyable: true + :dedent: + :start-after: // start-update-many-pullfilter + :end-before: // end-update-many-pullfilter + :emphasize-lines: 15-19 + + .. tab:: Asynchronous + :tabid: async + + .. literalinclude:: /includes/code-examples/update-many/UpdateManyArrays.cs + :language: csharp + :copyable: true + :dedent: + :start-after: // start-update-many-pullfilter-async + :end-before: // end-update-many-pullfilter-async + :emphasize-lines: 15-20 + + .. replacement:: positional-code-example-tabs + + .. tabs:: + + .. tab:: Positional Operator (Sync) + :tabid: sync + + .. include:: /includes/update-many/positional-operator-code-intro.rst + + .. literalinclude:: /includes/code-examples/update-many/UpdateManyArrays.cs + :language: csharp + :copyable: true + :dedent: + :start-after: // start-update-many-positional + :end-before: // end-update-many-positional + + .. include:: /includes/update-arrays-positional-operator-note.rst + + .. tab:: Positional Operator (Async) + :tabid: async + + .. include:: /includes/update-many/positional-operator-code-intro.rst + + .. literalinclude:: /includes/code-examples/update-many/UpdateManyArrays.cs + :language: csharp + :copyable: true + :dedent: + :start-after: // start-update-many-positional-async + :end-before: // end-update-many-positional-async + + .. include:: /includes/update-arrays-positional-operator-note.rst + + .. tab:: LINQ (Sync) + :tabid: linq-sync + + .. include:: /includes/update-many/positional-linq-code-intro.rst + + .. literalinclude:: /includes/code-examples/update-many/UpdateManyArrays.cs + :language: csharp + :copyable: true + :dedent: + :start-after: // start-update-many-positional-linq + :end-before: // end-update-many-positional-linq + + .. tab:: LINQ (Async) + :tabid: linq-async + + .. include:: /includes/update-many/positional-linq-code-intro.rst + + .. literalinclude:: /includes/code-examples/update-many/UpdateManyArrays.cs + :language: csharp + :copyable: true + :dedent: + :start-after: // start-update-many-positional-linq-async + :end-before: // end-update-many-positional-linq-async + + .. replacement:: filteredpositional-code-example-tabs + + .. tabs:: + + .. tab:: Positional Operator (Sync) + :tabid: sync + + .. include:: /includes/update-many/filteredpositional-operator-code-intro.rst + + .. literalinclude:: /includes/code-examples/update-many/UpdateManyArrays.cs + :language: csharp + :copyable: true + :dedent: + :start-after: // start-update-many-filteredpositional + :end-before: // end-update-many-filteredpositional + + .. tab:: Positional Operator (Async) + :tabid: async + + .. include:: /includes/update-many/filteredpositional-operator-code-intro.rst + + .. literalinclude:: /includes/code-examples/update-many/UpdateManyArrays.cs + :language: csharp + :copyable: true + :dedent: + :start-after: // start-update-many-filteredpositional-async + :end-before: // end-update-many-filteredpositional-async + + .. tab:: LINQ (Sync) + :tabid: linq-sync + + .. include:: /includes/update-many/filteredpositional-linq-code-intro.rst + + .. literalinclude:: /includes/code-examples/update-many/UpdateManyArrays.cs + :language: csharp + :copyable: true + :dedent: + :start-after: // start-update-many-filteredpositional-linq + :end-before: // end-update-many-filteredpositional-linq + + .. tab:: LINQ (Async) + :tabid: linq-async + + .. include:: /includes/update-many/filteredpositional-linq-code-intro.rst + + .. literalinclude:: /includes/code-examples/update-many/UpdateManyArrays.cs + :language: csharp + :copyable: true + :dedent: + :start-after: // start-update-many-filteredpositional-linq-async + :end-before: // end-update-many-filteredpositional-linq-async + + .. replacement:: allpositional-code-example-tabs + + .. tabs:: + + .. tab:: Positional Operator (Sync) + :tabid: sync + + .. include:: /includes/update-many/allpositional-operator-code-intro.rst + + .. literalinclude:: /includes/code-examples/update-many/UpdateManyArrays.cs + :language: csharp + :copyable: true + :dedent: + :start-after: // start-update-many-allpositional + :end-before: // end-update-many-allpositional + + .. tab:: Positional Operator (Async) + :tabid: async + + .. include:: /includes/update-many/allpositional-operator-code-intro.rst + + .. literalinclude:: /includes/code-examples/update-many/UpdateManyArrays.cs + :language: csharp + :copyable: true + :dedent: + :start-after: // start-update-many-allpositional-async + :end-before: // end-update-many-allpositional-async + + .. tab:: LINQ (Sync) + :tabid: linq-sync + + .. include:: /includes/update-many/allpositional-linq-code-intro.rst + + .. literalinclude:: /includes/code-examples/update-many/UpdateManyArrays.cs + :language: csharp + :copyable: true + :dedent: + :start-after: // start-update-many-allpositional-linq + :end-before: // end-update-many-allpositional-linq + + .. tab:: LINQ (Async) + :tabid: linq-async + + .. include:: /includes/update-many/allpositional-linq-code-intro.rst + + .. literalinclude:: /includes/code-examples/update-many/UpdateManyArrays.cs + :language: csharp + :copyable: true + :dedent: + :start-after: // start-update-many-allpositional-linq-async + :end-before: // end-update-many-allpositional-linq-async \ No newline at end of file diff --git a/source/fundamentals/crud/write-operations/update-many/fields.txt b/source/fundamentals/crud/write-operations/update-many/fields.txt new file mode 100644 index 00000000..13c9e3a4 --- /dev/null +++ b/source/fundamentals/crud/write-operations/update-many/fields.txt @@ -0,0 +1,28 @@ +.. _csharp-update-many-fields: + +============= +Update Fields +============= + +.. contents:: On this page + :local: + :backlinks: none + :depth: 2 + :class: singlecol + +.. facet:: + :name: genre + :values: reference + +.. meta:: + :keywords: synchronous, asynchronous + +.. include:: /includes/page-templates/update/fields.rst + + .. replacement:: one-or-multiple + + multiple MongoDB documents + + .. replacement:: update-page-link + + :ref:`` \ No newline at end of file diff --git a/source/fundamentals/crud/write-operations/update-one.txt b/source/fundamentals/crud/write-operations/update-one.txt new file mode 100644 index 00000000..192bf0ed --- /dev/null +++ b/source/fundamentals/crud/write-operations/update-one.txt @@ -0,0 +1,114 @@ +.. _csharp-update-one: + +========== +Update One +========== + +.. contents:: On this page + :local: + :backlinks: none + :depth: 2 + :class: singlecol + +.. facet:: + :name: genre + :values: reference + +.. meta:: + :keywords: synchronous, asynchronous + +.. toctree:: + :caption: Update Documents + + Fields + Arrays + +.. include:: /includes/page-templates/update/update.rst + + .. replacement:: sync-method + + ``UpdateOne()`` + + .. replacement:: async-method + + ``UpdateOneAsync()`` + + .. replacement:: document-or-documents + + document + + .. replacement:: fields-link + + :ref:`csharp-update-one-fields` + + .. replacement:: arrays-link + + :ref:`csharp-update-one-arrays` + + .. replacement:: single-or-multiple + + a single document + + .. replacement:: usage-examples-link + + :ref:`csharp-examples-update-one` + + .. replacement:: sync-api-link + + `UpdateOne() <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.IMongoCollection-1.UpdateOne.html>`__ + + .. replacement:: async-api-link + + `UpdateOneAsync() <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.IMongoCollection-1.UpdateOneAsync.html>`__ + + .. replacement:: instruqt-lab-component + + .. replacement:: instruqt-lab-instructions + + .. replacement:: combine-code-example-tabs + + .. tabs:: + + .. tab:: Synchronous + :tabid: sync + + .. literalinclude:: /includes/code-examples/update-one/UpdateOne.cs + :language: csharp + :copyable: true + :dedent: + :start-after: // start-combine-sync + :end-before: // end-combine-sync + + .. tab:: Asynchronous + :tabid: async + + .. literalinclude:: /includes/code-examples/update-one/UpdateOne.cs + :language: csharp + :copyable: true + :dedent: + :start-after: // start-combine-async + :end-before: // end-combine-async + + .. replacement:: pipeline-code-example-tabs + + .. tabs:: + + .. tab:: Synchronous + :tabid: sync + + .. literalinclude:: /includes/code-examples/update-one/UpdateOne.cs + :language: csharp + :copyable: true + :dedent: + :start-after: // start-pipeline-sync + :end-before: // end-pipeline-sync + + .. tab:: Asynchronous + :tabid: async + + .. literalinclude:: /includes/code-examples/update-one/UpdateOne.cs + :language: csharp + :copyable: true + :dedent: + :start-after: // start-pipeline-async + :end-before: // end-pipeline-async \ No newline at end of file diff --git a/source/fundamentals/crud/write-operations/update-one/arrays.txt b/source/fundamentals/crud/write-operations/update-one/arrays.txt new file mode 100644 index 00000000..91ca58dc --- /dev/null +++ b/source/fundamentals/crud/write-operations/update-one/arrays.txt @@ -0,0 +1,426 @@ +.. _csharp-update-one-arrays: + +============= +Update Arrays +============= + +.. contents:: On this page + :local: + :backlinks: none + :depth: 2 + :class: singlecol + +.. facet:: + :name: genre + :values: reference + +.. meta:: + :keywords: synchronous, asynchronous + +.. include:: /includes/page-templates/update/arrays.rst + + .. replacement:: sync-method + + ``UpdateOne()`` + + .. replacement:: async-method + + ``UpdateOneAsync()`` + + .. replacement:: matching-document-or-documents + + the matching document + + .. replacement:: pusheach-section-ref + + .. _csharp-update-one-arrays-pusheach: + + .. replacement:: pusheach-method-link + + :ref:`PushEach() ` + + .. replacement:: update-page-link + + :ref:`` + + .. replacement:: push-code-example-tabs + + .. tabs:: + + .. tab:: Synchronous + :tabid: sync + + .. literalinclude:: /includes/code-examples/update-one/UpdateOneArrays.cs + :language: csharp + :copyable: true + :dedent: + :start-after: // start-update-one-push + :end-before: // end-update-one-push + + .. tab:: Asynchronous + :tabid: async + + .. literalinclude:: /includes/code-examples/update-one/UpdateOneArrays.cs + :language: csharp + :copyable: true + :dedent: + :start-after: // start-update-one-push-async + :end-before: // end-update-one-push-async + + .. replacement:: addtoset-code-example-tabs + + .. tabs:: + + .. tab:: Synchronous + :tabid: sync + + .. literalinclude:: /includes/code-examples/update-one/UpdateOneArrays.cs + :language: csharp + :copyable: true + :dedent: + :start-after: // start-update-one-addtoset + :end-before: // end-update-one-addtoset + + .. tab:: Asynchronous + :tabid: async + + .. literalinclude:: /includes/code-examples/update-one/UpdateOneArrays.cs + :language: csharp + :copyable: true + :dedent: + :start-after: // start-update-one-addtoset-async + :end-before: // end-update-one-addtoset-async + + .. replacement:: pusheach-code-example-tabs + + .. tabs:: + + .. tab:: Synchronous + :tabid: sync + + .. literalinclude:: /includes/code-examples/update-one/UpdateOneArrays.cs + :language: csharp + :copyable: true + :dedent: + :start-after: // start-update-one-pusheach + :end-before: // end-update-one-pusheach + + .. tab:: Asynchronous + :tabid: async + + .. literalinclude:: /includes/code-examples/update-one/UpdateOneArrays.cs + :language: csharp + :copyable: true + :dedent: + :start-after: // start-update-one-pusheach-async + :end-before: // end-update-one-pusheach-async + + .. replacement:: addtoseteach-code-example-tabs + + .. tabs:: + + .. tab:: Synchronous + :tabid: sync + + .. literalinclude:: /includes/code-examples/update-one/UpdateOneArrays.cs + :language: csharp + :copyable: true + :dedent: + :start-after: // start-update-one-addtoseteach + :end-before: // end-update-one-addtoseteach + + .. tab:: Asynchronous + :tabid: async + + .. literalinclude:: /includes/code-examples/update-one/UpdateOneArrays.cs + :language: csharp + :copyable: true + :dedent: + :start-after: // start-update-one-addtoseteach-async + :end-before: // end-update-one-addtoseteach-async + + .. replacement:: popfirst-code-example-tabs + + .. tabs:: + + .. tab:: Synchronous + :tabid: sync + + .. literalinclude:: /includes/code-examples/update-one/UpdateOneArrays.cs + :language: csharp + :copyable: true + :dedent: + :start-after: // start-update-one-popfirst + :end-before: // end-update-one-popfirst + + .. tab:: Asynchronous + :tabid: async + + .. literalinclude:: /includes/code-examples/update-one/UpdateOneArrays.cs + :language: csharp + :copyable: true + :dedent: + :start-after: // start-update-one-popfirst-async + :end-before: // end-update-one-popfirst-async + + .. replacement:: poplast-code-example-tabs + + .. tabs:: + + .. tab:: Synchronous + :tabid: sync + + .. literalinclude:: /includes/code-examples/update-one/UpdateOneArrays.cs + :language: csharp + :copyable: true + :dedent: + :start-after: // start-update-one-poplast + :end-before: // end-update-one-poplast + + .. tab:: Asynchronous + :tabid: async + + .. literalinclude:: /includes/code-examples/update-one/UpdateOneArrays.cs + :language: csharp + :copyable: true + :dedent: + :start-after: // start-update-one-poplast-async + :end-before: // end-update-one-poplast-async + + .. replacement:: pull-code-example-tabs + + .. tabs:: + + .. tab:: Synchronous + :tabid: sync + + .. literalinclude:: /includes/code-examples/update-one/UpdateOneArrays.cs + :language: csharp + :copyable: true + :dedent: + :start-after: // start-update-one-pull + :end-before: // end-update-one-pull + :emphasize-lines: 13-17 + + .. tab:: Asynchronous + :tabid: async + + .. literalinclude:: /includes/code-examples/update-one/UpdateOneArrays.cs + :language: csharp + :copyable: true + :dedent: + :start-after: // start-update-one-pull-async + :end-before: // end-update-one-pull-async + :emphasize-lines: 13-17 + + .. replacement:: pullall-code-example-tabs + + .. tabs:: + + .. tab:: Synchronous + :tabid: sync + + .. literalinclude:: /includes/code-examples/update-one/UpdateOneArrays.cs + :language: csharp + :copyable: true + :dedent: + :start-after: // start-update-one-pullall + :end-before: // end-update-one-pullall + :emphasize-lines: 15-20 + + .. tab:: Asynchronous + :tabid: async + + .. literalinclude:: /includes/code-examples/update-one/UpdateOneArrays.cs + :language: csharp + :copyable: true + :dedent: + :start-after: // start-update-one-pullall-async + :end-before: // end-update-one-pullall-async + :emphasize-lines: 15-20 + + .. replacement:: pullfilter-code-example-tabs + + .. tabs:: + + .. tab:: Synchronous + :tabid: sync + + .. literalinclude:: /includes/code-examples/update-one/UpdateOneArrays.cs + :language: csharp + :copyable: true + :dedent: + :start-after: // start-update-one-pullfilter + :end-before: // end-update-one-pullfilter + :emphasize-lines: 15-19 + + .. tab:: Asynchronous + :tabid: async + + .. literalinclude:: /includes/code-examples/update-one/UpdateOneArrays.cs + :language: csharp + :copyable: true + :dedent: + :start-after: // start-update-one-pullfilter-async + :end-before: // end-update-one-pullfilter-async + :emphasize-lines: 15-19 + + .. replacement:: positional-code-example-tabs + + .. tabs:: + + .. tab:: Positional Operator (Sync) + :tabid: sync + + .. include:: /includes/update-one/positional-operator-code-intro.rst + + .. literalinclude:: /includes/code-examples/update-one/UpdateOneArrays.cs + :language: csharp + :copyable: true + :dedent: + :start-after: // start-update-one-positional + :end-before: // end-update-one-positional + + .. include:: /includes/update-arrays-positional-operator-note.rst + + .. tab:: Positional Operator (Async) + :tabid: async + + .. include:: /includes/update-one/positional-operator-code-intro.rst + + .. literalinclude:: /includes/code-examples/update-one/UpdateOneArrays.cs + :language: csharp + :copyable: true + :dedent: + :start-after: // start-update-one-positional-async + :end-before: // end-update-one-positional-async + + .. include:: /includes/update-arrays-positional-operator-note.rst + + .. tab:: LINQ (Sync) + :tabid: linq-sync + + .. include:: /includes/update-one/positional-linq-code-intro.rst + + .. literalinclude:: /includes/code-examples/update-one/UpdateOneArrays.cs + :language: csharp + :copyable: true + :dedent: + :start-after: // start-update-one-positional-linq + :end-before: // end-update-one-positional-linq + + .. tab:: LINQ (Async) + :tabid: linq-async + + .. include:: /includes/update-one/positional-linq-code-intro.rst + + .. literalinclude:: /includes/code-examples/update-one/UpdateOneArrays.cs + :language: csharp + :copyable: true + :dedent: + :start-after: // start-update-one-positional-linq-async + :end-before: // end-update-one-positional-linq-async + + .. replacement:: filteredpositional-code-example-tabs + + .. tabs:: + + .. tab:: Positional Operator (Sync) + :tabid: sync + + .. include:: /includes/update-many/filteredpositional-operator-code-intro.rst + + .. literalinclude:: /includes/code-examples/update-one/UpdateOneArrays.cs + :language: csharp + :copyable: true + :dedent: + :start-after: // start-update-one-filteredpositional + :end-before: // end-update-one-filteredpositional + + .. tab:: Positional Operator (Async) + :tabid: async + + .. include:: /includes/update-many/filteredpositional-operator-code-intro.rst + + .. literalinclude:: /includes/code-examples/update-one/UpdateOneArrays.cs + :language: csharp + :copyable: true + :dedent: + :start-after: // start-update-one-filteredpositional-async + :end-before: // end-update-one-filteredpositional-async + + .. tab:: LINQ (Sync) + :tabid: linq-sync + + .. include:: /includes/update-many/filteredpositional-linq-code-intro.rst + + .. literalinclude:: /includes/code-examples/update-one/UpdateOneArrays.cs + :language: csharp + :copyable: true + :dedent: + :start-after: // start-update-one-filteredpositional-linq + :end-before: // end-update-one-filteredpositional-linq + + .. tab:: LINQ (Async) + :tabid: linq-async + + .. include:: /includes/update-many/filteredpositional-linq-code-intro.rst + + .. literalinclude:: /includes/code-examples/update-one/UpdateOneArrays.cs + :language: csharp + :copyable: true + :dedent: + :start-after: // start-update-one-filteredpositional-linq-async + :end-before: // end-update-one-filteredpositional-linq-async + + .. replacement:: allpositional-code-example-tabs + + .. tabs:: + + .. tab:: Positional Operator (Sync) + :tabid: sync + + .. include:: /includes/update-one/allpositional-operator-code-intro.rst + + .. literalinclude:: /includes/code-examples/update-one/UpdateOneArrays.cs + :language: csharp + :copyable: true + :dedent: + :start-after: // start-update-one-allpositional + :end-before: // end-update-one-allpositional + + .. tab:: Positional Operator (Async) + :tabid: async + + .. include:: /includes/update-one/allpositional-operator-code-intro.rst + + .. literalinclude:: /includes/code-examples/update-one/UpdateOneArrays.cs + :language: csharp + :copyable: true + :dedent: + :start-after: // start-update-one-allpositional-async + :end-before: // end-update-one-allpositional-async + + .. tab:: LINQ (Sync) + :tabid: linq-sync + + .. include:: /includes/update-one/allpositional-linq-code-intro.rst + + .. literalinclude:: /includes/code-examples/update-one/UpdateOneArrays.cs + :language: csharp + :copyable: true + :dedent: + :start-after: // start-update-one-allpositional-linq + :end-before: // end-update-one-allpositional-linq + + .. tab:: LINQ (Async) + :tabid: linq-async + + .. include:: /includes/update-one/allpositional-linq-code-intro.rst + + .. literalinclude:: /includes/code-examples/update-one/UpdateOneArrays.cs + :language: csharp + :copyable: true + :dedent: + :start-after: // start-update-one-allpositional-linq-async + :end-before: // end-update-one-allpositional-linq-async \ No newline at end of file diff --git a/source/fundamentals/crud/write-operations/update-one/fields.txt b/source/fundamentals/crud/write-operations/update-one/fields.txt new file mode 100644 index 00000000..0f89433e --- /dev/null +++ b/source/fundamentals/crud/write-operations/update-one/fields.txt @@ -0,0 +1,28 @@ +.. _csharp-update-one-fields: + +============= +Update Fields +============= + +.. contents:: On this page + :local: + :backlinks: none + :depth: 2 + :class: singlecol + +.. facet:: + :name: genre + :values: reference + +.. meta:: + :keywords: synchronous, asynchronous + +.. include:: /includes/page-templates/update/fields.rst + + .. replacement:: one-or-multiple + + one MongoDB document + + .. replacement:: update-page-link + + :ref:`` \ No newline at end of file diff --git a/source/includes/atlas-sample-data.rst b/source/includes/atlas-sample-data.rst new file mode 100644 index 00000000..46d24320 --- /dev/null +++ b/source/includes/atlas-sample-data.rst @@ -0,0 +1,28 @@ +Sample Data +~~~~~~~~~~~ + +The examples in this guide use the ``restaurants`` collection +from the ``sample_restaurants`` database. The documents in this +collection use the following ``Restaurant``, ``Address``, and ``GradeEntry`` +classes as models: + +.. literalinclude:: /includes/code-examples/Restaurant.cs + :language: csharp + :copyable: + :dedent: + +.. literalinclude:: /includes/code-examples/Address.cs + :language: csharp + :copyable: + :dedent: + +.. literalinclude:: /includes/code-examples/GradeEntry.cs + :language: csharp + :copyable: + :dedent: + +.. include:: /includes/convention-pack-note.rst + +This collection is from the :atlas:`sample datasets ` provided +by Atlas. See the :ref:`` to learn how to create a free MongoDB cluster +and load this sample data. \ No newline at end of file diff --git a/source/includes/code-examples/replace-one/ReplaceOne.cs b/source/includes/code-examples/replace-one/ReplaceOne.cs index cb68232e..4f37ae43 100644 --- a/source/includes/code-examples/replace-one/ReplaceOne.cs +++ b/source/includes/code-examples/replace-one/ReplaceOne.cs @@ -14,7 +14,8 @@ public class ReplaceOne public static void Main(string[] args) { - try { + try + { Setup(); // Creates a filter for all restaurant documents that have a "cuisine" value of "Pizza" @@ -36,8 +37,10 @@ public static void Main(string[] args) _restaurantsCollection.ReplaceOneAsync(filter, oldPizzaRestaurant); Console.WriteLine("done."); - // Prints a message if any exceptions occur during the operation - } catch (MongoException me) { + // Prints a message if any exceptions occur during the operation + } + catch (MongoException me) + { Console.WriteLine("Unable to replace due to an error: " + me); } } @@ -49,17 +52,12 @@ private static ReplaceOneResult ReplaceOneRestaurant() var filter = Builders.Filter .Eq(r => r.Cuisine, "Pizza"); - // Finds the ID of the first restaurant document that matches the filter - var oldPizzaRestaurant = _restaurantsCollection.Find(filter).First(); - var oldId = oldPizzaRestaurant.Id; - // Generates a new restaurant document Restaurant newPizzaRestaurant = new() { - Id = oldId, Name = "Mongo's Pizza", Cuisine = "Pizza", - Address = new() + Address = new Address() { Street = "Pizza St", ZipCode = "10003" @@ -72,6 +70,36 @@ private static ReplaceOneResult ReplaceOneRestaurant() // end-replace-one } + private static ReplaceOneResult ReplaceOneRestaurantWithOptions() + { + // start-replace-one-sync-with-options + // Creates a filter for all restaurant documents that have a "cuisine" value of "Pizza" + var filter = Builders.Filter + .Eq(r => r.Cuisine, "Pizza"); + + // Generates a new restaurant document + Restaurant newPizzaRestaurant = new() + { + Name = "Mongo's Pizza", + Cuisine = "Pizza", + Address = new Address() + { + Street = "Pizza St", + ZipCode = "10003" + }, + Borough = "Manhattan", + }; + + var options = new ReplaceOptions + { + BypassDocumentValidation = true + }; + + // Replaces the existing restaurant document with the new document + return _restaurantsCollection.ReplaceOne(filter, newPizzaRestaurant, options); + // end-replace-one-sync-with-options + } + private static void Setup() { // Allows automapping of the camelCase database fields to models diff --git a/source/includes/code-examples/replace-one/ReplaceOneAsync.cs b/source/includes/code-examples/replace-one/ReplaceOneAsync.cs index 2bba474c..e3e79743 100644 --- a/source/includes/code-examples/replace-one/ReplaceOneAsync.cs +++ b/source/includes/code-examples/replace-one/ReplaceOneAsync.cs @@ -14,7 +14,8 @@ public class ReplaceOneAsync public static async Task Main(string[] args) { - try { + try + { Setup(); // Creates a filter for all restaurant documents that have a "cuisine" value of "Pizza" @@ -36,30 +37,27 @@ public static async Task Main(string[] args) await _restaurantsCollection.ReplaceOneAsync(filter, oldPizzaRestaurant); Console.WriteLine("done."); - // Prints a message if any exceptions occur during the operation - } catch (MongoException me) { + // Prints a message if any exceptions occur during the operation + } + catch (MongoException me) + { Console.WriteLine("Unable to replace due to an error: " + me); } } - private static async Task ReplaceOneRestaurant() + private static async Task ReplaceOneRestaurantAsync() { // start-replace-one-async // Creates a filter for all restaurant documents that have a "cuisine" value of "Pizza" var filter = Builders.Filter .Eq(r => r.Cuisine, "Pizza"); - // Finds the ID of the first restaurant document that matches the filter - var oldPizzaRestaurant = _restaurantsCollection.Find(filter).First(); - var oldId = oldPizzaRestaurant.Id; - // Generates a new restaurant document Restaurant newPizzaRestaurant = new() { - Id = oldId, Name = "Mongo's Pizza", Cuisine = "Pizza", - Address = new() + Address = new Address() { Street = "Pizza St", ZipCode = "10003" @@ -71,6 +69,35 @@ private static async Task ReplaceOneRestaurant() return await _restaurantsCollection.ReplaceOneAsync(filter, newPizzaRestaurant); // end-replace-one-async } + private static async Task ReplaceOneRestaurantAsyncWithOptions() + { + // start-replace-one-async-with-options + // Creates a filter for all restaurant documents that have a "cuisine" value of "Pizza" + var filter = Builders.Filter + .Eq(r => r.Cuisine, "Pizza"); + + // Generates a new restaurant document + Restaurant newPizzaRestaurant = new() + { + Name = "Mongo's Pizza", + Cuisine = "Pizza", + Address = new Address() + { + Street = "Pizza St", + ZipCode = "10003" + }, + Borough = "Manhattan", + }; + + var options = new ReplaceOptions + { + BypassDocumentValidation = true + }; + + // Asynchronously replaces the existing restaurant document with the new document + return await _restaurantsCollection.ReplaceOneAsync(filter, newPizzaRestaurant, options); + // end-replace-one-async-with-options + } private static void Setup() { diff --git a/source/includes/code-examples/update-many/UpdateMany.cs b/source/includes/code-examples/update-many/UpdateMany.cs index b8eb7317..e010110c 100644 --- a/source/includes/code-examples/update-many/UpdateMany.cs +++ b/source/includes/code-examples/update-many/UpdateMany.cs @@ -18,7 +18,8 @@ public class UpdateMany public static void Main(string[] args) { - try { + try + { Setup(); // Prints extra space for console readability @@ -39,10 +40,12 @@ public static void Main(string[] args) ResetSampleData(); Console.WriteLine("done."); - // Prints a message if any exceptions occur during the operation - } catch (MongoException me) { + // Prints a message if any exceptions occur during the operation + } + catch (MongoException me) + { Console.WriteLine("Unable to update due to an error: " + me); - } + } } private static UpdateResult UpdateManyRestaurants() @@ -95,44 +98,68 @@ private static void ResetSampleData() _restaurantsCollection.UpdateMany(filter, update); } -} + public static void CombineUpdates() + { + // start-combine-sync + var filter = Builders.Filter + .Eq("cuisine", "Pizza"); -public class Restaurant -{ - public ObjectId Id { get; set; } + var combinedUpdate = Builders.Update.Combine( + Builders.Update.Set("cuisine", "French"), + Builders.Update.Unset("borough") + ); - public string Name { get; set; } + _restaurantsCollection.UpdateMany(filter, combinedUpdate); + // end-combine-sync + } - [BsonElement("restaurant_id")] - public string RestaurantId { get; set; } + public static async Task CombineUpdatesAsync() + { + // start-combine-async + var filter = Builders.Filter + .Eq("cuisine", "Pizza"); - public string Cuisine { get; set; } + var combinedUpdate = Builders.Update.Combine( + Builders.Update.Set("cuisine", "French"), + Builders.Update.Unset("borough") + ); - public Address Address { get; set; } + await _restaurantsCollection.UpdateManyAsync(filter, combinedUpdate); + // end-combine-async + } + public static void PipelineUpdate() + { + // start-pipeline-sync + var filter = Builders.Filter + .Eq("cuisine", "Pizza"); - public string Borough { get; set; } + var updatePipeline = Builders.Update.Pipeline( + PipelineDefinition.Create( + new BsonDocument("$set", new BsonDocument("cuisine", "French")), + new BsonDocument("$unset", "borough") + ) + ); - public List Grades { get; set; } -} + _restaurantsCollection.UpdateMany(filter, updatePipeline); + // end-pipeline-sync + } -public class Address -{ - public string Building { get; set; } + public static async Task PipelineUpdateAsync() + { + // start-pipeline-async + var filter = Builders.Filter + .Eq("cuisine", "Pizza"); - [BsonElement("coord")] - public double[] Coordinates { get; set; } + var updatePipeline = Builders.Update.Pipeline( + PipelineDefinition.Create( + new BsonDocument("$set", new BsonDocument("cuisine", "French")), + new BsonDocument("$unset", "borough") + ) + ); - public string Street { get; set; } + await _restaurantsCollection.UpdateManyAsync(filter, updatePipeline); + // end-pipeline-async + } - [BsonElement("zipcode")] - public string ZipCode { get; set; } } -public class GradeEntry -{ - public DateTime Date { get; set; } - - public string Grade { get; set; } - - public float? Score { get; set; } -} diff --git a/source/includes/code-examples/update-many/UpdateManyArrays.cs b/source/includes/code-examples/update-many/UpdateManyArrays.cs new file mode 100644 index 00000000..dcf2c2ac --- /dev/null +++ b/source/includes/code-examples/update-many/UpdateManyArrays.cs @@ -0,0 +1,618 @@ +using MongoDB.Bson; +using MongoDB.Bson.Serialization.Conventions; +using MongoDB.Driver; +using MongoDB.Driver.Linq; +using WriteData.Models; + +namespace CSharpExamples.WriteData; + +public class UpdateManyArrays +{ + private static IMongoCollection _restaurantsCollection; + private static string _mongoConnectionString = ""; + + public static void Setup() + { + // This allows automapping of the camelCase database fields to our models. + var camelCaseConvention = new ConventionPack { new CamelCaseElementNameConvention() }; + ConventionRegistry.Register("CamelCase", camelCaseConvention, type => true); + + // Establish the connection to MongoDB and get the restaurants database + var mongoClient = new MongoClient(_mongoConnectionString); + var restaurantsDatabase = mongoClient.GetDatabase("sample_restaurants"); + _restaurantsCollection = restaurantsDatabase.GetCollection("restaurants"); + } + + public static UpdateResult UpdateManyPush() + { + // start-update-many-push + var filter = Builders.Filter.Eq("name", "Downtown Deli"); + + var update = Builders.Update + .Push(restaurant => restaurant.Grades, new GradeEntry() + { + Date = DateTime.Now, + Grade = "A", + Score = 96 + }); + + var result = _restaurantsCollection.UpdateMany(filter, update); + + return result; + // end-update-many-push + } + + public static async Task UpdateManyPushAsync() + { + // start-update-many-push-async + var filter = Builders.Filter.Eq("name", "Downtown Deli"); + + var update = Builders.Update + .Push(restaurant => restaurant.Grades, new GradeEntry() + { + Date = DateTime.Now, + Grade = "A", + Score = 96 + }); + + var result = await _restaurantsCollection.UpdateManyAsync(filter, update); + + return result; + // end-update-many-push-async + } + + public static UpdateResult UpdateManyAddToSet() + { + // start-update-many-addtoset + var filter = Builders.Filter.Eq("name", "Downtown Deli"); + + var firstGradeEntry = _restaurantsCollection.Find(filter).FirstOrDefault().Grades[0]; + + var update = Builders.Update + .AddToSet(restaurant => restaurant.Grades, firstGradeEntry); + + var result = _restaurantsCollection.UpdateMany(filter, update); + + return result; + // end-update-many-addtoset + } + + public static async Task UpdateManyAddToSetAsync() + { + // start-update-many-addtoset-async + var filter = Builders.Filter.Eq("name", "Downtown Deli"); + + var firstGradeEntry = _restaurantsCollection.Find(filter).FirstOrDefault().Grades[0]; + + var update = Builders.Update + .AddToSet(restaurant => restaurant.Grades, firstGradeEntry); + + var result = await _restaurantsCollection.UpdateManyAsync(filter, update); + + return result; + // end-update-many-addtoset-async + } + + public static UpdateResult UpdateManyPushEach() + { + // start-update-many-pusheach + var filter = Builders.Filter.Eq("name", "Downtown Deli"); + + var newGrades = new List + { + new GradeEntry { Date = DateTime.Now, Grade = "A", Score = 95 }, + new GradeEntry { Date = DateTime.Now, Grade = "B+", Score = 89,} + }; + + var scoreSort = Builders.Sort.Descending(g => g.Score); + + var update = Builders.Update.PushEach( + "Grades", + newGrades, + position: 0, + sort: scoreSort); + + var result = _restaurantsCollection.UpdateMany(filter, update); + + return result; + // end-update-many-pusheach + } + + public static async Task UpdateManyPushEachAsync() + { + // start-update-many-pusheach-async + var filter = Builders.Filter.Eq("name", "Downtown Deli"); + + var newGrades = new List + { + new GradeEntry { Date = DateTime.Now, Grade = "A", Score = 95 }, + new GradeEntry { Date = DateTime.Now, Grade = "B+", Score = 89,} + }; + + var scoreSort = Builders.Sort.Descending(g => g.Score); + + var update = Builders.Update.PushEach( + "Grades", + newGrades, + position: 0, + sort: scoreSort); + + var result = await _restaurantsCollection.UpdateManyAsync(filter, update); + + return result; + // end-update-many-pusheach-async + } + + public static UpdateResult UpdateManyAddToSetEach() + { + // start-update-many-addtoseteach + var filter = Builders.Filter.Eq("name", "Downtown Deli"); + + var doc = _restaurantsCollection.Find(filter).FirstOrDefault(); + var firstGradeEntries = new List { doc.Grades[0], doc.Grades[1] }; + + var update = Builders.Update + .AddToSetEach(restaurant => restaurant.Grades, firstGradeEntries); + + var result = _restaurantsCollection.UpdateMany(filter, update); + + return result; + // end-update-many-addtoseteach + } + + public static async Task UpdateManyAddToSetEachAsync() + { + // start-update-many-addtoseteach-async + var filter = Builders.Filter.Eq("name", "Downtown Deli"); + + var doc = _restaurantsCollection.Find(filter).FirstOrDefault(); + var firstGradeEntries = new List { doc.Grades[0], doc.Grades[1] }; + + var update = Builders.Update + .AddToSetEach(restaurant => restaurant.Grades, firstGradeEntries); + + var result = await _restaurantsCollection.UpdateManyAsync(filter, update); + + return result; + // end-update-many-addtoseteach-async + } + + public static UpdateResult UpdateManyPopFirst() + { + // start-update-many-popfirst + var filter = Builders.Filter.Eq("name", "Downtown Deli"); + + var update = Builders.Update + .PopFirst(restaurant => restaurant.Grades); + + var result = _restaurantsCollection.UpdateMany(filter, update); + + return result; + // end-update-many-popfirst + } + + public static async Task UpdateManyPopFirstAsync() + { + // start-update-many-popfirst-async + var filter = Builders.Filter.Eq("name", "Downtown Deli"); + + var update = Builders.Update + .PopFirst(restaurant => restaurant.Grades); + + var result = await _restaurantsCollection.UpdateManyAsync(filter, update); + + return result; + // end-update-many-popfirst-async + } + + public static UpdateResult UpdateManyPopLast() + { + // start-update-many-poplast + var filter = Builders.Filter.Eq("name", "Downtown Deli"); + + var update = Builders.Update + .PopLast(restaurant => restaurant.Grades); + + var result = _restaurantsCollection.UpdateMany(filter, update); + + return result; + // end-update-many-poplast + } + + public static async Task UpdateManyPopLastAsync() + { + // start-update-many-poplast-async + var filter = Builders.Filter.Eq("name", "Downtown Deli"); + + var update = Builders.Update + .PopLast(restaurant => restaurant.Grades); + + var result = await _restaurantsCollection.UpdateManyAsync(filter, update); + + return result; + // end-update-many-poplast-async + } + + public static UpdateResult UpdateManyPull() + { + // start-update-many-pull + var filter = Builders.Filter.Eq("name", "Downtown Deli"); + + // Add duplicate values to Grades array + var newGrades = new List + { + new GradeEntry { Date = DateTime.MinValue, Grade = "A", Score = 95 }, + new GradeEntry { Date = DateTime.MinValue, Grade = "A", Score = 95,} + }; + var addUpdate = Builders.Update + .PushEach("Grades", newGrades); + _restaurantsCollection.UpdateMany(filter, addUpdate); + + // Remove duplicates from Grades array + var pullUpdate = Builders.Update + .Pull(restaurant => restaurant.Grades, newGrades[0]); + + var result = _restaurantsCollection.UpdateMany(filter, pullUpdate); + + return result; + // end-update-many-pull + } + + public static async Task UpdateManyPullAsync() + { + // start-update-many-pull-async + var filter = Builders.Filter.Eq("name", "Downtown Deli"); + + // Add duplicate values to Grades array + var newGrades = new List + { + new GradeEntry { Date = DateTime.MinValue, Grade = "A", Score = 95 }, + new GradeEntry { Date = DateTime.MinValue, Grade = "A", Score = 95,} + }; + var addUpdate = Builders.Update + .PushEach("Grades", newGrades); + await _restaurantsCollection.UpdateManyAsync(filter, addUpdate); + + // Remove duplicates from Grades array + var pullUpdate = Builders.Update + .Pull(restaurant => restaurant.Grades, newGrades[0]); + + var result = await _restaurantsCollection.UpdateManyAsync(filter, pullUpdate); + + return result; + // end-update-many-pull-async + } + + public static UpdateResult UpdateManyPullAll() + { + // start-update-many-pullall + var filter = Builders.Filter.Eq("name", "Downtown Deli"); + + // Add duplicate values to Grades array + var newGrades = new List + { + new GradeEntry { Date = DateTime.MinValue, Grade = "A", Score = 95 }, + new GradeEntry { Date = DateTime.MinValue, Grade = "A", Score = 95,}, + new GradeEntry { Date = DateTime.MinValue, Grade = "B", Score = 85 }, + new GradeEntry { Date = DateTime.MinValue, Grade = "B", Score = 85,} + }; + var addUpdate = Builders.Update + .PushEach("Grades", newGrades); + _restaurantsCollection.UpdateMany(filter, addUpdate); + + // Remove duplicates from Grades array + var gradesToRemove = new List { newGrades[0], newGrades[2] }; + var pullUpdate = Builders.Update + .PullAll(restaurant => restaurant.Grades, gradesToRemove); + + var result = _restaurantsCollection.UpdateMany(filter, pullUpdate); + + return result; + // end-update-many-pullall + } + + public static async Task UpdateManyPullAllAsync() + { + // start-update-many-pullall-async + var filter = Builders.Filter.Eq("name", "Downtown Deli"); + + // Add duplicate values to Grades array + var newGrades = new List + { + new GradeEntry { Date = DateTime.MinValue, Grade = "A", Score = 95 }, + new GradeEntry { Date = DateTime.MinValue, Grade = "A", Score = 95,}, + new GradeEntry { Date = DateTime.MinValue, Grade = "B", Score = 85 }, + new GradeEntry { Date = DateTime.MinValue, Grade = "B", Score = 85,} + }; + var addUpdate = Builders.Update + .PushEach("Grades", newGrades); + await _restaurantsCollection.UpdateManyAsync(filter, addUpdate); + + // Remove duplicates from Grades array + var gradesToRemove = new List { newGrades[0], newGrades[2] }; + var pullUpdate = Builders.Update + .PullAll(restaurant => restaurant.Grades, gradesToRemove); + + var result = await _restaurantsCollection.UpdateManyAsync(filter, pullUpdate); + + return result; + // end-update-many-pullall-async + } + + public static UpdateResult UpdateManyPullFilter() + { + // start-update-many-pullfilter + var filter = Builders.Filter.Eq("name", "Downtown Deli"); + + // Add GradeEntry values with "Grade = F" to Grades array + var newGrades = new List + { + new GradeEntry { Date = DateTime.Now, Grade = "F", Score = 10 }, + new GradeEntry { Date = DateTime.Now, Grade = "F", Score = 21,}, + new GradeEntry { Date = DateTime.Now, Grade = "F", Score = 47 }, + new GradeEntry { Date = DateTime.Now, Grade = "F", Score = 6,} + }; + var addUpdate = Builders.Update + .PushEach("Grades", newGrades); + _restaurantsCollection.UpdateMany(filter, addUpdate); + + // Remove all "Grade = F" values from Grades array + var pullUpdate = Builders.Update + .PullFilter(restaurant => restaurant.Grades, gradeEntry => gradeEntry.Grade == "F"); + + var result = _restaurantsCollection.UpdateMany(filter, pullUpdate); + + return result; + // end-update-many-pullfilter + } + + public static async Task UpdateManyPullFilterAsync() + { + // start-update-many-pullfilter-async + var filter = Builders.Filter.Eq("name", "Downtown Deli"); + + // Add GradeEntry values with "Grade = F" to Grades array + var newGrades = new List + { + new GradeEntry { Date = DateTime.Now, Grade = "F", Score = 10 }, + new GradeEntry { Date = DateTime.Now, Grade = "F", Score = 21,}, + new GradeEntry { Date = DateTime.Now, Grade = "F", Score = 47 }, + new GradeEntry { Date = DateTime.Now, Grade = "F", Score = 6,} + }; + var addUpdate = Builders.Update + .PushEach("Grades", newGrades); + await _restaurantsCollection.UpdateManyAsync(filter, addUpdate); + + // Remove all "Grade = F" values from Grades array + var pullUpdate = Builders.Update + .PullFilter(restaurant => restaurant.Grades, gradeEntry => gradeEntry.Grade == "F"); + + var result = await _restaurantsCollection.UpdateManyAsync(filter, pullUpdate); + + return result; + // end-update-many-pullfilter-async + } + + public static UpdateResult UpdateManyPositional() + { + // start-update-many-positional + var filter = Builders.Filter.Eq("name", "Downtown Deli") & + Builders.Filter.Eq("grades.grade", "A"); + + // Set Score = 100 in first GradeEntry where Grade = "A" + var update = Builders.Update + .Set("grades.$.score", 100); + + var result = _restaurantsCollection.UpdateMany(filter, update); + + return result; + // end-update-many-positional + } + + public static UpdateResult UpdateManyPositionalLinq() + { + // start-update-many-positional-linq + var filter = Builders.Filter.Eq("name", "Downtown Deli") & + Builders.Filter.Eq("grades.grade", "A"); + + // Set Score = 100 in first GradeEntry where Grade = "A" + var update = Builders.Update + .Set(restaurant => restaurant.Grades.FirstMatchingElement().Score, 100); + + var result = _restaurantsCollection.UpdateMany(filter, update); + return result; + // end-update-many-positional-linq + } + + public static async Task UpdateManyPositionalAsync() + { + // start-update-many-positional-async + var filter = Builders.Filter.Eq("name", "Downtown Deli") & + Builders.Filter.Eq("grades.grade", "A"); + + // Set Score = 100 in first GradeEntry where Grade = "A" + var update = Builders.Update + .Set("grades.$.score", 100); + + var result = await _restaurantsCollection.UpdateManyAsync(filter, update); + + return result; + // end-update-many-positional-async + } + + public static async Task UpdateManyPositionalLinqAsync() + { + // start-update-many-positional-linq-async + var filter = Builders.Filter.Eq("name", "Downtown Deli") & + Builders.Filter.Eq("grades.grade", "A"); + + // Set Score = 100 in first GradeEntry where Grade = "A" + var update = Builders.Update + .Set(restaurant => restaurant.Grades.FirstMatchingElement().Score, 100); + + var result = await _restaurantsCollection.UpdateManyAsync(filter, update); + + return result; + // end-update-many-positional-linq-async + } + + public static UpdateResult UpdateManyAllPositional() + { + // start-update-many-allpositional + var filter = Builders.Filter.Eq("name", "Downtown Deli"); + + // Set Score = 100 in all GradeEntry objects + var update = Builders.Update + .Set("grades.$[].score", 100); + + var result = _restaurantsCollection.UpdateMany(filter, update); + + return result; + // end-update-many-allpositional + } + + public static UpdateResult UpdateManyAllPositionalLinq() + { + // start-update-many-allpositional-linq + var filter = Builders.Filter.Eq("name", "Downtown Deli"); + + // Set Score = 100 in all GradeEntry objects + var update = Builders.Update + .Set(restaurant => restaurant.Grades.AllElements().Score, 100); + + var result = _restaurantsCollection.UpdateMany(filter, update); + + return result; + // end-update-many-allpositional-linq + } + + public static async Task UpdateManyAllPositionalAsync() + { + // start-update-many-allpositional-async + var filter = Builders.Filter.Eq("name", "Downtown Deli"); + + // Set Score = 100 in all GradeEntry objects + var update = Builders.Update + .Set("grades.$[].score", 100); + + var result = await _restaurantsCollection.UpdateManyAsync(filter, update); + + return result; + // end-update-many-allpositional-async + } + + public static async Task UpdateManyAllPositionalLinqAsync() + { + // start-update-many-allpositional-linq-async + var filter = Builders.Filter.Eq("name", "Downtown Deli"); + + // Set Score = 100 in all GradeEntry objects + var update = Builders.Update + .Set(restaurant => restaurant.Grades.AllElements().Score, 100); + + var result = await _restaurantsCollection.UpdateManyAsync(filter, update); + + return result; + // end-update-many-allpositional-linq-async + } + + public static UpdateResult UpdateManyFilteredPositional() + { + // start-update-many-filteredpositional + var filter = Builders.Filter.Eq("name", "Downtown Deli"); + + var arrayFilters = new List + { + new BsonDocumentArrayFilterDefinition( + new BsonDocument + { + { "gradeEntry.score", new BsonDocument { { "$gte", 94} } } + }) + }; + + // Set Grade = "A" in all GradeEntry objects where Score >= 94 + var update = Builders.Update + .Set("grades.$[gradeEntry].grade", "A"); + + var updateOptions = new UpdateOptions { ArrayFilters = arrayFilters }; + var result = _restaurantsCollection.UpdateMany(filter, update, updateOptions); + + return result; + // end-update-many-filteredpositional + } + + public static UpdateResult UpdateManyFilteredPositionalLinq() + { + // start-update-many-filteredpositional-linq + var filter = Builders.Filter.Eq("name", "Downtown Deli"); + + var arrayFilters = new List + { + new BsonDocumentArrayFilterDefinition( + new BsonDocument + { + { "gradeEntry.score", new BsonDocument { { "$gte", 94} } } + }) + }; + + // Set Grade = "A" in all GradeEntry objects where Score >= 94 + var update = Builders.Update + .Set(restaurant => restaurant.Grades.AllMatchingElements("gradeEntry").Grade, "A"); + + var updateOptions = new UpdateOptions { ArrayFilters = arrayFilters }; + var result = _restaurantsCollection.UpdateMany(filter, update, updateOptions); + + return result; + // end-update-many-filteredpositional-linq + } + + public static async Task UpdateManyFilteredPositionalAsync() + { + // start-update-many-filteredpositional-async + var filter = Builders.Filter.Eq("name", "Downtown Deli"); + + var arrayFilters = new List + { + new BsonDocumentArrayFilterDefinition( + new BsonDocument + { + { "gradeEntry.score", new BsonDocument { { "$gte", 94} } } + }) + }; + + // Set Grade = "A" in all GradeEntry objects where Score >= 94 + var update = Builders.Update + .Set("grades.$[gradeEntry].grade", "A"); + + var updateOptions = new UpdateOptions { ArrayFilters = arrayFilters }; + var result = await _restaurantsCollection.UpdateManyAsync(filter, update, updateOptions); + + return result; + // end-update-many-filteredpositional-async + } + + public static async Task UpdateManyFilteredPositionalLinqAsync() + { + // start-update-many-filteredpositional-linq-async + var filter = Builders.Filter.Eq("name", "Downtown Deli"); + + var arrayFilters = new List + { + new BsonDocumentArrayFilterDefinition( + new BsonDocument + { + { "gradeEntry.score", new BsonDocument { { "$gte", 94} } } + }) + }; + + // Set Grade = "A" in all GradeEntry objects where Score >= 94 + var update = Builders.Update + .Set(restaurant => restaurant.Grades.AllMatchingElements("gradeEntry").Grade, "A"); + + var updateOptions = new UpdateOptions { ArrayFilters = arrayFilters }; + var result = await _restaurantsCollection.UpdateManyAsync(filter, update, updateOptions); + + return result; + // end-update-many-filteredpositional-linq-async + } +} \ No newline at end of file diff --git a/source/includes/code-examples/update-one/UpdateOne.cs b/source/includes/code-examples/update-one/UpdateOne.cs index 1c1ded85..a4e57a60 100644 --- a/source/includes/code-examples/update-one/UpdateOne.cs +++ b/source/includes/code-examples/update-one/UpdateOne.cs @@ -14,7 +14,8 @@ public class UpdateOne public static void Main(string[] args) { - try { + try + { Setup(); // Prints extra space for console readability @@ -25,8 +26,10 @@ public static void Main(string[] args) Console.WriteLine($"Updated documents: {syncResult.ModifiedCount}"); ResetSampleData(); - // Prints a message if any exceptions occur during the operation - } catch (MongoException me) { + // Prints a message if any exceptions occur during the operation + } + catch (MongoException me) + { Console.WriteLine("Unable to update due to an error: " + me); } } @@ -34,23 +37,124 @@ public static void Main(string[] args) private static UpdateResult UpdateOneRestaurant() { // start-update-one - const string oldValue = "Bagels N Buns"; - const string newValue = "2 Bagels 2 Buns"; - // Creates a filter for all documents with a "name" of "Bagels N Buns" var filter = Builders.Filter - .Eq(restaurant => restaurant.Name, oldValue); + .Eq(restaurant => restaurant.Name, "Bagels N Buns"); // Creates instructions to update the "name" field of the first document // that matches the filter var update = Builders.Update - .Set(restaurant => restaurant.Name, newValue); + .Set(restaurant => restaurant.Name, "2 Bagels 2 Buns"); // Updates the first document that has a "name" value of "Bagels N Buns" return _restaurantsCollection.UpdateOne(filter, update); // end-update-one } + public static UpdateResult UpdateOneRestaurantArray() + { + // start-update-one-array + var filter = Builders.Filter + .Eq("name", "Downtown Deli"); + + var update = Builders.Update + .Push(restaurant => restaurant.Grades, new GradeEntry() + { + Date = DateTime.Now, + Grade = "A", + Score = 96 + }); + + var result = _restaurantsCollection.UpdateOne(filter, update); + + return result; + // end-update-one-array + } + + public static async Task UpdateOneRestaurantArrayAsync() + { + // start-update-one-array-async + var filter = Builders.Filter + .Eq("name", "Downtown Deli"); + + var update = Builders.Update + .Push(restaurant => restaurant.Grades, new GradeEntry() + { + Date = DateTime.Now, + Grade = "A", + Score = 96 + }); + + var result = await _restaurantsCollection.UpdateOneAsync(filter, update); + + return result; + // end-update-one-array-async + } + + public static void CombineUpdates() + { + // start-combine-sync + var filter = Builders.Filter + .Eq("name", "Downtown Deli"); + + var combinedUpdate = Builders.Update.Combine( + Builders.Update.Set("cuisine", "French"), + Builders.Update.Unset("borough") + ); + + _restaurantsCollection.UpdateOne(filter, combinedUpdate); + // end-combine-sync + } + + public static async Task CombineUpdatesAsync() + { + // start-combine-async + var filter = Builders.Filter + .Eq("name", "Downtown Deli"); + + var combinedUpdate = Builders.Update.Combine( + Builders.Update.Set("cuisine", "French"), + Builders.Update.Unset("borough") + ); + + await _restaurantsCollection.UpdateOneAsync(filter, combinedUpdate); + // end-combine-async + } + + public static void PipelineUpdate() + { + // start-pipeline-sync + var filter = Builders.Filter + .Eq("name", "Downtown Deli"); + + var updatePipeline = Builders.Update.Pipeline( + PipelineDefinition.Create( + new BsonDocument("$set", new BsonDocument("cuisine", "French")), + new BsonDocument("$unset", "borough") + ) + ); + + _restaurantsCollection.UpdateOne(filter, updatePipeline); + // end-pipeline-sync + } + + public static async Task PipelineUpdateAsync() + { + // start-pipeline-async + var filter = Builders.Filter + .Eq("name", "Downtown Deli"); + + var updatePipeline = Builders.Update.Pipeline( + PipelineDefinition.Create( + new BsonDocument("$set", new BsonDocument("cuisine", "French")), + new BsonDocument("$unset", "borough") + ) + ); + + await _restaurantsCollection.UpdateOneAsync(filter, updatePipeline); + // end-pipeline-async + } + private static void Setup() { // Allows automapping of the camelCase database fields to models diff --git a/source/includes/code-examples/update-one/UpdateOneArrays.cs b/source/includes/code-examples/update-one/UpdateOneArrays.cs new file mode 100644 index 00000000..361ab0cc --- /dev/null +++ b/source/includes/code-examples/update-one/UpdateOneArrays.cs @@ -0,0 +1,616 @@ +using MongoDB.Bson; +using MongoDB.Bson.Serialization.Conventions; +using MongoDB.Driver; +using MongoDB.Driver.Linq; +using WriteData.Models; + +namespace CSharpExamples.WriteData; + +public static class UpdateOneArrays +{ + private static IMongoCollection _restaurantsCollection; + private static string _mongoConnectionString = ""; + + public static void Setup() + { + // This allows automapping of the camelCase database fields to our models. + var camelCaseConvention = new ConventionPack { new CamelCaseElementNameConvention() }; + ConventionRegistry.Register("CamelCase", camelCaseConvention, type => true); + + // Establish the connection to MongoDB and get the restaurants database + var mongoClient = new MongoClient(_mongoConnectionString); + var restaurantsDatabase = mongoClient.GetDatabase("sample_restaurants"); + _restaurantsCollection = restaurantsDatabase.GetCollection("restaurants"); + } + + public static UpdateResult UpdateOnePush() + { + // start-update-one-push + var filter = Builders.Filter.Eq("name", "Downtown Deli"); + + var update = Builders.Update + .Push(restaurant => restaurant.Grades, new GradeEntry() + { + Date = DateTime.Now, + Grade = "A", + Score = 96 + }); + + var result = _restaurantsCollection.UpdateOne(filter, update); + + return result; + // end-update-one-push + } + + public static async Task UpdateOnePushAsync() + { + // start-update-one-push-async + var filter = Builders.Filter.Eq("name", "Downtown Deli"); + + var update = Builders.Update + .Push(restaurant => restaurant.Grades, new GradeEntry() + { + Date = DateTime.Now, + Grade = "A", + Score = 96 + }); + + var result = await _restaurantsCollection.UpdateOneAsync(filter, update); + + return result; + // end-update-one-push-async + } + + public static UpdateResult UpdateOneAddToSet() + { + // start-update-one-addtoset + var filter = Builders.Filter.Eq("name", "Downtown Deli"); + + var firstGradeEntry = _restaurantsCollection.Find(filter).FirstOrDefault().Grades[0]; + + var update = Builders.Update + .AddToSet(restaurant => restaurant.Grades, firstGradeEntry); + + var result = _restaurantsCollection.UpdateOne(filter, update); + + return result; + // end-update-one-addtoset + } + + public static async Task UpdateOneAddToSetAsync() + { + // start-update-one-addtoset-async + var filter = Builders.Filter.Eq("name", "Downtown Deli"); + + var firstGradeEntry = _restaurantsCollection.Find(filter).FirstOrDefault().Grades[0]; + + var update = Builders.Update + .AddToSet(restaurant => restaurant.Grades, firstGradeEntry); + + var result = await _restaurantsCollection.UpdateOneAsync(filter, update); + + return result; + // end-update-one-addtoset-async + } + + public static UpdateResult UpdateOnePushEach() + { + // start-update-one-pusheach + var filter = Builders.Filter.Eq("name", "Downtown Deli"); + + var newGrades = new List + { + new GradeEntry { Date = DateTime.Now, Grade = "A", Score = 95 }, + new GradeEntry { Date = DateTime.Now, Grade = "B+", Score = 89,} + }; + + var scoreSort = Builders.Sort.Descending(g => g.Score); + + var update = Builders.Update.PushEach( + "Grades", + newGrades, + position: 0, + sort: scoreSort); + + var result = _restaurantsCollection.UpdateOne(filter, update); + + return result; + // end-update-one-pusheach + } + + public static async Task UpdateOnePushEachAsync() + { + // start-update-one-pusheach-async + var filter = Builders.Filter.Eq("name", "Downtown Deli"); + + var newGrades = new List + { + new GradeEntry { Date = DateTime.Now, Grade = "A", Score = 95 }, + new GradeEntry { Date = DateTime.Now, Grade = "B+", Score = 89,} + }; + + var scoreSort = Builders.Sort.Descending(g => g.Score); + + var update = Builders.Update.PushEach( + "Grades", + newGrades, + position: 0, + sort: scoreSort); + + var result = await _restaurantsCollection.UpdateOneAsync(filter, update); + + return result; + // end-update-one-pusheach-async + } + + public static UpdateResult UpdateOneAddToSetEach() + { + // start-update-one-addtoseteach + var filter = Builders.Filter.Eq("name", "Downtown Deli"); + + var doc = _restaurantsCollection.Find(filter).FirstOrDefault(); + var firstGradeEntries = new List { doc.Grades[0], doc.Grades[1] }; + + var update = Builders.Update + .AddToSetEach(restaurant => restaurant.Grades, firstGradeEntries); + + var result = _restaurantsCollection.UpdateOne(filter, update); + + return result; + // end-update-one-addtoseteach + } + + public static async Task UpdateOneAddToSetEachAsync() + { + // start-update-one-addtoseteach-async + var filter = Builders.Filter.Eq("name", "Downtown Deli"); + + var doc = _restaurantsCollection.Find(filter).FirstOrDefault(); + var firstGradeEntries = new List { doc.Grades[0], doc.Grades[1] }; + + var update = Builders.Update + .AddToSetEach(restaurant => restaurant.Grades, firstGradeEntries); + + var result = await _restaurantsCollection.UpdateOneAsync(filter, update); + + return result; + // end-update-one-addtoseteach-async + } + + public static UpdateResult UpdateOnePopFirst() + { + // start-update-one-popfirst + var filter = Builders.Filter.Eq("name", "Downtown Deli"); + + var update = Builders.Update + .PopFirst(restaurant => restaurant.Grades); + + var result = _restaurantsCollection.UpdateOne(filter, update); + + return result; + // end-update-one-popfirst + } + + public static async Task UpdateOnePopFirstAsync() + { + // start-update-one-popfirst-async + var filter = Builders.Filter.Eq("name", "Downtown Deli"); + + var update = Builders.Update + .PopFirst(restaurant => restaurant.Grades); + + var result = await _restaurantsCollection.UpdateOneAsync(filter, update); + + return result; + // end-update-one-popfirst-async + } + + public static UpdateResult UpdateOnePopLast() + { + // start-update-one-poplast + var filter = Builders.Filter.Eq("name", "Downtown Deli"); + + var update = Builders.Update + .PopLast(restaurant => restaurant.Grades); + + var result = _restaurantsCollection.UpdateOne(filter, update); + + return result; + // end-update-one-poplast + } + + public static async Task UpdateOnePopLastAsync() + { + // start-update-one-poplast-async + var filter = Builders.Filter.Eq("name", "Downtown Deli"); + + var update = Builders.Update + .PopLast(restaurant => restaurant.Grades); + + var result = await _restaurantsCollection.UpdateOneAsync(filter, update); + + return result; + // end-update-one-poplast-async + } + + public static UpdateResult UpdateOnePull() + { + // start-update-one-pull + var filter = Builders.Filter.Eq("name", "Downtown Deli"); + + // Add duplicate values to Grades array + var newGrades = new List + { + new GradeEntry { Date = DateTime.MinValue, Grade = "A", Score = 95 }, + new GradeEntry { Date = DateTime.MinValue, Grade = "A", Score = 95,} + }; + var addUpdate = Builders.Update + .PushEach("Grades", newGrades); + _restaurantsCollection.UpdateOne(filter, addUpdate); + + // Remove duplicates from Grades array + var pullUpdate = Builders.Update + .Pull(restaurant => restaurant.Grades, newGrades[0]); + + var result = _restaurantsCollection.UpdateOne(filter, pullUpdate); + + return result; + // end-update-one-pull + } + + public static async Task UpdateOnePullAsync() + { + // start-update-one-pull-async + var filter = Builders.Filter.Eq("name", "Downtown Deli"); + + // Add duplicate values to Grades array + var newGrades = new List + { + new GradeEntry { Date = DateTime.MinValue, Grade = "A", Score = 95 }, + new GradeEntry { Date = DateTime.MinValue, Grade = "A", Score = 95,} + }; + var addUpdate = Builders.Update + .PushEach("Grades", newGrades); + await _restaurantsCollection.UpdateOneAsync(filter, addUpdate); + + // Remove duplicates from Grades array + var pullUpdate = Builders.Update + .Pull(restaurant => restaurant.Grades, newGrades[0]); + + var result = await _restaurantsCollection.UpdateOneAsync(filter, pullUpdate); + + return result; + // end-update-one-pull-async + } + + public static UpdateResult UpdateOnePullAll() + { + // start-update-one-pullall + var filter = Builders.Filter.Eq("name", "Downtown Deli"); + + // Add duplicate values to Grades array + var newGrades = new List + { + new GradeEntry { Date = DateTime.MinValue, Grade = "A", Score = 95 }, + new GradeEntry { Date = DateTime.MinValue, Grade = "A", Score = 95,}, + new GradeEntry { Date = DateTime.MinValue, Grade = "B", Score = 85 }, + new GradeEntry { Date = DateTime.MinValue, Grade = "B", Score = 85,} + }; + var addUpdate = Builders.Update + .PushEach("Grades", newGrades); + _restaurantsCollection.UpdateOne(filter, addUpdate); + + // Remove duplicates from Grades array + var gradesToRemove = new List { newGrades[0], newGrades[2] }; + var pullUpdate = Builders.Update + .PullAll(restaurant => restaurant.Grades, gradesToRemove); + + var result = _restaurantsCollection.UpdateOne(filter, pullUpdate); + + return result; + // end-update-one-pullall + } + + public static async Task UpdateOnePullAllAsync() + { + // start-update-one-pullall-async + var filter = Builders.Filter.Eq("name", "Downtown Deli"); + + // Add duplicate values to Grades array + var newGrades = new List + { + new GradeEntry { Date = DateTime.MinValue, Grade = "A", Score = 95 }, + new GradeEntry { Date = DateTime.MinValue, Grade = "A", Score = 95,}, + new GradeEntry { Date = DateTime.MinValue, Grade = "B", Score = 85 }, + new GradeEntry { Date = DateTime.MinValue, Grade = "B", Score = 85,} + }; + var addUpdate = Builders.Update + .PushEach("Grades", newGrades); + await _restaurantsCollection.UpdateOneAsync(filter, addUpdate); + + // Remove duplicates from Grades array + var gradesToRemove = new List { newGrades[0], newGrades[2] }; + var pullUpdate = Builders.Update + .PullAll(restaurant => restaurant.Grades, gradesToRemove); + + var result = await _restaurantsCollection.UpdateOneAsync(filter, pullUpdate); + + return result; + // end-update-one-pullall-async + } + + public static UpdateResult UpdateOnePullFilter() + { + // start-update-one-pullfilter + var filter = Builders.Filter.Eq("name", "Downtown Deli"); + + // Add GradeEntry values with "Grade = F" to Grades array + var newGrades = new List + { + new GradeEntry { Date = DateTime.Now, Grade = "F", Score = 10 }, + new GradeEntry { Date = DateTime.Now, Grade = "F", Score = 21,}, + new GradeEntry { Date = DateTime.Now, Grade = "F", Score = 47 }, + new GradeEntry { Date = DateTime.Now, Grade = "F", Score = 6,} + }; + var addUpdate = Builders.Update + .PushEach("Grades", newGrades); + _restaurantsCollection.UpdateOne(filter, addUpdate); + + // Remove all "Grade = F" values from Grades array + var pullUpdate = Builders.Update + .PullFilter(restaurant => restaurant.Grades, gradeEntry => gradeEntry.Grade == "F"); + + var result = _restaurantsCollection.UpdateOne(filter, pullUpdate); + + return result; + // end-update-one-pullfilter + } + + public static async Task UpdateOnePullFilterAsync() + { + // start-update-one-pullfilter-async + var filter = Builders.Filter.Eq("name", "Downtown Deli"); + + // Add GradeEntry values with "Grade = F" to Grades array + var newGrades = new List + { + new GradeEntry { Date = DateTime.Now, Grade = "F", Score = 10 }, + new GradeEntry { Date = DateTime.Now, Grade = "F", Score = 21,}, + new GradeEntry { Date = DateTime.Now, Grade = "F", Score = 47 }, + new GradeEntry { Date = DateTime.Now, Grade = "F", Score = 6,} + }; + var addUpdate = Builders.Update + .PushEach("Grades", newGrades); + await _restaurantsCollection.UpdateOneAsync(filter, addUpdate); + + // Remove all "Grade = F" values from Grades array + var pullUpdate = Builders.Update + .PullFilter(restaurant => restaurant.Grades, gradeEntry => gradeEntry.Grade == "F"); + + var result = await _restaurantsCollection.UpdateOneAsync(filter, pullUpdate); + + return result; + // end-update-one-pullfilter-async + } + + public static UpdateResult UpdateOnePositional() + { + // start-update-one-positional + var filter = Builders.Filter.Eq("name", "Downtown Deli") & + Builders.Filter.Eq("grades.grade", "A"); + + // Set Score = 100 in first GradeEntry where Grade = "A" + var update = Builders.Update + .Set("grades.$.score", 100); + + var result = _restaurantsCollection.UpdateOne(filter, update); + + return result; + // end-update-one-positional + } + + public static UpdateResult UpdateOnePositionalLinq() + { + // start-update-one-positional-linq + var filter = Builders.Filter.Eq("name", "Downtown Deli") & + Builders.Filter.Eq("grades.grade", "A"); + + var update = Builders.Update + .Set(restaurant => restaurant.Grades.FirstMatchingElement().Score, 100); + + var result = _restaurantsCollection.UpdateOne(filter, update); + return result; + // end-update-one-positional-linq + } + + public static async Task UpdateOnePositionalAsync() + { + // start-update-one-positional-async + var filter = Builders.Filter.Eq("name", "Downtown Deli") & + Builders.Filter.Eq("grades.grade", "A"); + + // Set Score = 100 in first GradeEntry where Grade = "A" + var update = Builders.Update + .Set("grades.$.score", 100); + + var result = await _restaurantsCollection.UpdateOneAsync(filter, update); + + return result; + // end-update-one-positional-async + } + + public static async Task UpdateOnePositionalLinqAsync() + { + // start-update-one-positional-linq-async + var filter = Builders.Filter.Eq("name", "Downtown Deli") & + Builders.Filter.Eq("grades.grade", "A"); + + var update = Builders.Update + .Set(restaurant => restaurant.Grades.FirstMatchingElement().Score, 100); + + var result = await _restaurantsCollection.UpdateOneAsync(filter, update); + + return result; + // end-update-one-positional-linq-async + } + + public static UpdateResult UpdateOneAllPositional() + { + // start-update-one-allpositional + var filter = Builders.Filter.Eq("name", "Downtown Deli"); + + // Set Score = 100 in all GradeEntry objects + var update = Builders.Update + .Set("grades.$[].score", 100); + + var result = _restaurantsCollection.UpdateOne(filter, update); + + return result; + // end-update-one-allpositional + } + + public static UpdateResult UpdateOneAllPositionalLinq() + { + // start-update-one-allpositional-linq + var filter = Builders.Filter.Eq("name", "Downtown Deli"); + + // Set Score = 100 in all GradeEntry objects + var update = Builders.Update + .Set(restaurant => restaurant.Grades.AllElements().Score, 100); + + var result = _restaurantsCollection.UpdateOne(filter, update); + + return result; + // end-update-one-allpositional-linq + } + + public static async Task UpdateOneAllPositionalAsync() + { + // start-update-one-allpositional-async + var filter = Builders.Filter.Eq("name", "Downtown Deli"); + + // Set Score = 100 in all GradeEntry objects + var update = Builders.Update + .Set("grades.$[].score", 100); + + var result = await _restaurantsCollection.UpdateOneAsync(filter, update); + + return result; + // end-update-one-allpositional-async + } + + public static async Task UpdateOneAllPositionalLinqAsync() + { + // start-update-one-allpositional-linq-async + var filter = Builders.Filter.Eq("name", "Downtown Deli"); + + // Set Score = 100 in all GradeEntry objects + var update = Builders.Update + .Set(restaurant => restaurant.Grades.AllElements().Score, 100); + + var result = await _restaurantsCollection.UpdateOneAsync(filter, update); + + return result; + // end-update-one-allpositional-linq-async + } + + public static UpdateResult UpdateOneFilteredPositional() + { + // start-update-one-filteredpositional + var filter = Builders.Filter.Eq("name", "Downtown Deli"); + + var arrayFilters = new List + { + new BsonDocumentArrayFilterDefinition( + new BsonDocument + { + { "gradeEntry.score", new BsonDocument { { "$gte", 94} } } + }) + }; + + // Set Grade = "A" in all GradeEntry objects where Score >= 94 + var update = Builders.Update + .Set("grades.$[gradeEntry].grade", "A"); + + var updateOptions = new UpdateOptions { ArrayFilters = arrayFilters }; + var result = _restaurantsCollection.UpdateOne(filter, update, updateOptions); + + return result; + // end-update-one-filteredpositional + } + + public static UpdateResult UpdateOneFilteredPositionalLinq() + { + // start-update-one-filteredpositional-linq + var filter = Builders.Filter.Eq("name", "Downtown Deli"); + + var arrayFilters = new List + { + new BsonDocumentArrayFilterDefinition( + new BsonDocument + { + { "gradeEntry.score", new BsonDocument { { "$gte", 94} } } + }) + }; + + // Set Grade = "A" in all GradeEntry objects where Score >= 94 + var update = Builders.Update + .Set(restaurant => restaurant.Grades.AllMatchingElements("gradeEntry").Grade, "A"); + + var updateOptions = new UpdateOptions { ArrayFilters = arrayFilters }; + var result = _restaurantsCollection.UpdateOne(filter, update, updateOptions); + + return result; + // end-update-one-filteredpositional-linq + } + + public static async Task UpdateOneFilteredPositionalAsync() + { + // start-update-one-filteredpositional-async + var filter = Builders.Filter.Eq("name", "Downtown Deli"); + + var arrayFilters = new List + { + new BsonDocumentArrayFilterDefinition( + new BsonDocument + { + { "gradeEntry.score", new BsonDocument { { "$gte", 94} } } + }) + }; + + // Set Grade = "A" in all GradeEntry objects where Score >= 94 + var update = Builders.Update + .Set("grades.$[gradeEntry].grade", "A"); + + var updateOptions = new UpdateOptions { ArrayFilters = arrayFilters }; + var result = await _restaurantsCollection.UpdateOneAsync(filter, update, updateOptions); + + return result; + // end-update-one-filteredpositional-async + } + + public static async Task UpdateOneFilteredPositionalLinqAsync() + { + // start-update-one-filteredpositional-linq-async + var filter = Builders.Filter.Eq("name", "Downtown Deli"); + + var arrayFilters = new List + { + new BsonDocumentArrayFilterDefinition( + new BsonDocument + { + { "gradeEntry.score", new BsonDocument { { "$gte", 94} } } + }) + }; + + // Set Grade = "A" in all GradeEntry objects where Score >= 94 + var update = Builders.Update + .Set(restaurant => restaurant.Grades.AllMatchingElements("gradeEntry").Grade, "A"); + + var updateOptions = new UpdateOptions { ArrayFilters = arrayFilters }; + var result = await _restaurantsCollection.UpdateOneAsync(filter, update, updateOptions); + + return result; + // end-update-one-filteredpositional-linq-async + } +} \ No newline at end of file diff --git a/source/includes/code-examples/update-one/UpdateOneAsync.cs b/source/includes/code-examples/update-one/UpdateOneAsync.cs index 166174dc..f4dfe72b 100644 --- a/source/includes/code-examples/update-one/UpdateOneAsync.cs +++ b/source/includes/code-examples/update-one/UpdateOneAsync.cs @@ -14,7 +14,8 @@ public class UpdateOneAsync public static async Task Main(string[] args) { - try { + try + { Setup(); // Prints extra space for console readability @@ -25,8 +26,10 @@ public static async Task Main(string[] args) Console.WriteLine($"Updated documents: {asyncResult.ModifiedCount}"); ResetSampleData(); - // Prints a message if any exceptions occur during the operation - } catch (MongoException e) { + // Prints a message if any exceptions occur during the operation + } + catch (MongoException e) + { Console.WriteLine("Unable to update due to an error: " + me); } } @@ -34,17 +37,14 @@ public static async Task Main(string[] args) private static async Task UpdateOneRestaurantAsync() { // start-update-one-async - const string oldValue = "Bagels N Buns"; - const string newValue = "2 Bagels 2 Buns"; - // Creates a filter for all documents with a "name" of "Bagels N Buns" var filter = Builders.Filter - .Eq(restaurant => restaurant.Name, oldValue); + .Eq(restaurant => restaurant.Name, "Bagels N Buns"); // Creates instructions to update the "name" field of the first document // that matches the filter var update = Builders.Update - .Set(restaurant => restaurant.Name, newValue); + .Set(restaurant => restaurant.Name, "2 Bagels 2 Buns"); // Updates the first document that has a "name" value of "Bagels N Buns" return await _restaurantsCollection.UpdateOneAsync(filter, update); diff --git a/source/includes/method-overloads.rst b/source/includes/method-overloads.rst new file mode 100644 index 00000000..48d11b14 --- /dev/null +++ b/source/includes/method-overloads.rst @@ -0,0 +1,6 @@ +.. note:: Method Overloads + + Many of the methods on this page have multiple overloads. The examples + in this guide show only one definition of each method. For + more information about the available overloads, see the + `API documentation. <{+new-api-root+}/index.html>`__ \ No newline at end of file diff --git a/source/includes/page-templates/update/arrays.rst b/source/includes/page-templates/update/arrays.rst new file mode 100644 index 00000000..3a7e7521 --- /dev/null +++ b/source/includes/page-templates/update/arrays.rst @@ -0,0 +1,377 @@ +Overview +-------- + +On this page, you can learn how to create ``UpdateDefinition`` objects for array fields. +An ``UpdateDefinition`` object specifies the kind of update operation to perform, the +fields to update, and the new value for each field, if applicable. + +The {+driver-short+} supports the array update operators and modifiers described in the +:manual:`{+mdb-server+} manual `. +To create an ``UpdateDefinition`` object for one of these operators, call the corresponding +method from the ``Builders.Update`` property. +The following sections describe these methods in more detail. + +After you create an ``UpdateDefinition`` object, pass it to the |sync-method| +or |async-method| method. For more information about these methods, see +the |update-page-link| page. + +.. include:: /includes/method-overloads.rst + +.. include:: /includes/atlas-sample-data.rst + +Add One Value +------------- + +To add one value to the end of an array, call the ``Builders.Update.Push()`` method. +This method accepts the following parameters: + +.. list-table:: + :widths: 30 70 + :header-rows: 1 + + * - Parameter + - Description + + * - ``field`` + - An expression that specifies the array field to add a value to. + + **Data Type:** ``Expression>>`` + + * - ``value`` + - The value to add to the end of the array field. + + **Data Type:** ``TItem`` + +The following code example uses the ``Push()`` method to add a new ``GradeEntry`` object +to the ``Grades`` array in |matching-document-or-documents|: + +|push-code-example-tabs| + +.. tip:: Configure the Push Operation + + To add a value at a specific position in an array, or to sort or slice the array after + updating it, call the |pusheach-method-link| method instead. + +To add one value to the end of an array, *but only if it doesn't already exist in the array*, +call the ``Builders.Update.AddToSet()`` method. +{+mdb-server+} determines whether the value already exists in the array by +comparing the value's BSON representation to the BSON representation of each +other element in the array. + +The ``AddToSet()`` method accepts the following parameters: + +.. list-table:: + :widths: 30 70 + :header-rows: 1 + + * - Parameter + - Description + + * - ``field`` + - An expression that specifies the array field to add a value to. + + **Data Type:** ``Expression>>`` + + * - ``value`` + - The value to add to the end of the array field. + + **Data Type:** ``TItem`` + +The following code example calls the ``AddToSet()`` method to re-add the first +``GradeEntry`` object to the ``Grades`` array in |matching-document-or-documents|. Because +the value already exists in the array, the update operation does nothing. + +|addtoset-code-example-tabs| + +|pusheach-section-ref| + +Add Multiple Values +------------------- + +To add multiple values to an array, call the ``Builders.Update.PushEach()`` method. +This method accepts the following parameters: + +.. list-table:: + :widths: 30 70 + :header-rows: 1 + + * - Parameter + - Description + + * - ``field`` + - An expression that specifies the array field to add one or more values to. + + **Data Type:** ``Expression>>`` + + * - ``values`` + - The values to add to the array field. + + **Data Type:** ``IEnumerable`` + + * - ``slice`` + - The number of elements to keep in the array, counted from the start of the array + after updates. If the value is negative, + the method keeps the specified number of elements from the end of the array. + + **Data Type:** ``int?`` + + * - ``position`` + - The position in the array at which to add the values. By default, the method + adds the values to the end of the array. + + **Data Type:** ``int?`` + + * - ``sort`` + - A ``SortDefinition`` object that specifies how the driver sorts the array elements + after adding the new values. + + **Data Type:** `SortDefinition <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.SortDefinition-1.html>`__ + +The following code example uses the ``PushEach()`` method to add two new ``GradeEntry`` +objects to the start of the ``Grades`` array in |matching-document-or-documents|. +It then sorts the array elements in descending order by the values of their ``Score`` fields. + +|pusheach-code-example-tabs| + +To add multiple values to an array, *but only if they don't already exist in the array*, +call the ``Builders.Update.AddToSetEach()`` method. +This method accepts the following parameters: + +.. list-table:: + :widths: 30 70 + :header-rows: 1 + + * - Parameter + - Description + + * - ``field`` + - An expression that specifies the array field to add one or more values to. + + **Data Type:** ``Expression>>`` + + * - ``values`` + - The values to add to the array field. + + **Data Type:** ``IEnumerable`` + +The following code example calls the ``AddToSetEach()`` method to re-add the first +and second ``GradeEntry`` objects to the ``Grades`` array in |matching-document-or-documents|. +Because these values already exist in the array, the update operation does nothing. + +|addtoseteach-code-example-tabs| + +Remove Values +------------- + +The following sections explain how to remove values from an array field. + +First Value +~~~~~~~~~~~ + +To remove the first value from an array, call the ``Builders.Update.PopFirst()`` method. +This method accepts the following parameter: + +.. list-table:: + :widths: 30 70 + :header-rows: 1 + + * - Parameter + - Description + + * - ``field`` + - An expression that specifies the array field to remove the first value from. + + **Data Type:** ``Expression>>`` + +The following code example uses the ``PopFirst()`` method to remove the first ``GradeEntry`` +object from the ``Grades`` array in |matching-document-or-documents|: + +|popfirst-code-example-tabs| + +Last Value +~~~~~~~~~~ + +To remove the last value from an array, call the ``Builders.Update.PopLast()`` method: +This method accepts the following parameter: + +.. list-table:: + :widths: 30 70 + :header-rows: 1 + + * - Parameter + - Description + + * - ``field`` + - An expression that specifies the array field to remove the last value from. + + **Data Type:** ``Expression>>`` + +The following code example uses the ``PopLast()`` method to remove the last ``GradeEntry`` +object from the ``Grades`` array in |matching-document-or-documents|: + +|poplast-code-example-tabs| + +All Instances of a Value +~~~~~~~~~~~~~~~~~~~~~~~~ + +To remove all instances of a specific value from an array, call the +``Builders.Update.Pull()`` method. This method accepts the following parameters: + +.. list-table:: + :widths: 30 70 + :header-rows: 1 + + * - Parameter + - Description + + * - ``field`` + - An expression that specifies the array field to remove the values from. + + **Data Type:** ``Expression>>`` + + * - ``value`` + - The value to remove from the array field. + + **Data Type:** ``TItem`` + +The following code example uses the ``Pull()`` method to remove all instances of a +a specific ``GradeEntry`` object from the ``Grades`` array in |matching-document-or-documents|: + +|pull-code-example-tabs| + +All Instances of Multiple Values +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +To remove all instances of more than one specific value from an array, call the +``Builders.Update.PullAll()`` method. +This method accepts the following parameters: + +.. list-table:: + :widths: 30 70 + :header-rows: 1 + + * - Parameter + - Description + + * - ``field`` + - An expression that specifies the array field to remove the values from. + + **Data Type:** ``Expression>>`` + + * - ``values`` + - The values to remove from the array field. + + **Data Type:** ``IEnumerable`` + +The following code example uses the ``PullAll()`` method to remove all instances of two +specific ``GradeEntry`` objects from the ``Grades`` array in |matching-document-or-documents|: + +|pullall-code-example-tabs| + +All Values That Match a Condition +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +To remove all values that match a specific condition from an array, call the +``Builders.Update.PullFilter()`` method. +This method accepts the following parameters: + +.. list-table:: + :widths: 30 70 + :header-rows: 1 + + * - Parameter + - Description + + * - ``field`` + - An expression that specifies the array field to remove the values from. + + **Data Type:** ``Expression>>`` + + * - ``filter`` + - A query filter that specifies the condition for values to remove. + + **Data Type:** `FilterDefinition <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.FilterDefinition-1.html>`__ + +The following code example uses the ``PullFilter()`` method to remove all ``GradeEntry`` +objects where the ``Grade`` value is ``"F"`` from the ``Grades`` array in the +matching documents: + +|pullfilter-code-example-tabs| + +Update Matching Values +---------------------- + +To update a value in an array field, call the ``Builders.Update.Set()`` method. +This method accepts the following parameters: + +.. list-table:: + :widths: 30 70 + :header-rows: 1 + + * - Parameter + - Description + + * - ``field`` + - An expression that specifies the array field to update. + + **Data Type:** ``Expression>>`` + + * - ``value`` + - The new value to set into the array field. + + **Data Type:** ``TItem`` + +You can use the +:manual:`positional operator ` +with the ``Set()`` method to query and update specific values in the array. +If you're using the LINQ3 provider, the {+driver-short+} also supports LINQ syntax in +place of the positional operator. + +The following sections describe different ways to update matching values in an array field. + +First Matching Value +~~~~~~~~~~~~~~~~~~~~ + +To update the first value in an array, you can use either the positional operator +(``$``) or LINQ syntax. +Select a :guilabel:`Positional Operator` or :guilabel:`LINQ` tab to +see the corresponding syntax. + +|positional-code-example-tabs| + +All Matching Values +~~~~~~~~~~~~~~~~~~~ + +To update all values in an array that match a specified condition, you can use either +the filtered positional operator (``$[]``) or LINQ syntax. +Select a :guilabel:`Positional Operator` or :guilabel:`LINQ` tab to +see the corresponding syntax. + +|filteredpositional-code-example-tabs| + +All Values +~~~~~~~~~~ + +To update all values in an array that match a query filter, you can use either the +all-positional operator (``$[]``) or LINQ syntax. +Select a :guilabel:`Positional Operator` or :guilabel:`LINQ` tab to +see the corresponding syntax. + +|allpositional-code-example-tabs| + +API Documentation +----------------- + +For more information about any of the methods or types discussed in this +guide, see the following API documentation: + +- `Builders.Update.Push() <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.UpdateDefinitionBuilder-1.Push.html>`__ +- `Builders.Update.AddToSet() <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.UpdateDefinitionBuilder-1.AddToSet.html>`__ +- `Builders.Update.PushEach() <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.UpdateDefinitionBuilder-1.PushEach.html>`__ +- `Builders.Update.AddToSetEach() <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.UpdateDefinitionBuilder-1.AddToSetEach.html>`__ +- `Builders.Update.PopFirst() <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.UpdateDefinitionBuilder-1.PopFirst.html>`__ +- `Builders.Update.PopLast() <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.UpdateDefinitionBuilder-1.PopLast.html>`__ +- `Builders.Update.Pull() <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.UpdateDefinitionBuilder-1.Pull.html>`__ +- `Builders.Update.PullAll() <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.UpdateDefinitionBuilder-1.PullAll.html>`__ +- `Builders.Update.PullFilter() <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.UpdateDefinitionBuilder-1.PullFilter.html>`__ +- `Builders.Update.Set() <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.UpdateDefinitionBuilder-1.Set.html>`__ \ No newline at end of file diff --git a/source/includes/page-templates/update/fields.rst b/source/includes/page-templates/update/fields.rst new file mode 100644 index 00000000..287228ca --- /dev/null +++ b/source/includes/page-templates/update/fields.rst @@ -0,0 +1,235 @@ +Overview +-------- + +On this page, you can learn how to use the {+driver-long+} to update +fields in |one-or-multiple|. This page describes how to create ``UpdateDefinition`` +objects that specify the update operations you want to perform on fields. +You can pass these objects to the update methods described on the |update-page-link| +page. + +The {+driver-short+} supports the field update operators described in the +:manual:`{+mdb-server+} manual `. To specify an +update operation, call the corresponding method from the ``Builders.Update`` property. +The following sections describe these methods in more detail. + +.. include:: /includes/method-overloads.rst + +.. include:: /includes/atlas-sample-data.rst + +Increment a Value +----------------- + +To increment the value of a field by a specific amount, call the ``Builders.Update.Inc()`` +method. This method accepts the following parameters: + +.. list-table:: + :widths: 30 70 + :header-rows: 1 + + * - Parameter + - Description + + * - ``field`` + - An expression that specifies the field to increment. + + **Data Type:** ``Expression>`` + + * - ``value`` + - The amount to increment the field by. + + **Data Type:** ``TField`` + +Multiply a Value +---------------- + +To multiply the value of a field by a specific amount, call the ``Builders.Update.Mul()`` +method. This method accepts the following parameters: + +.. list-table:: + :widths: 30 70 + :header-rows: 1 + + * - Parameter + - Description + + * - ``field`` + - An expression that specifies the field to update. + + **Data Type:** ``Expression>`` + + * - ``value`` + - The amount to multiply the field by. + + **Data Type:** ``TField`` + +Rename a Field +-------------- + +To rename a field, call the ``Builders.Update.Rename()`` method. This method accepts +the following parameters: + +.. list-table:: + :widths: 30 70 + :header-rows: 1 + + * - Parameter + - Description + + * - ``field`` + - An expression that specifies the field to rename. + + **Data Type:** ``Expression>`` + + * - ``newName`` + - The new name for the field. + + **Data Type:** ``string`` + +Set a Value +----------- + +To set the value of a field to a specific value, call the ``Builders.Update.Set()`` +method. This method accepts the following parameters: + +.. list-table:: + :widths: 30 70 + :header-rows: 1 + + * - Parameter + - Description + + * - ``field`` + - An expression that specifies the field to update. + + **Data Type:** ``Expression>`` + + * - ``value`` + - The value to set the field to. + + **Data Type:** ``TField`` + +Set by Comparison +----------------- + +To update the value of the field to a specified value, but only if the specified value +is *greater than* the current value of the field, call the ``Builders.Update.Max()`` +method. This method accepts the following parameters: + +.. list-table:: + :widths: 30 70 + :header-rows: 1 + + * - Parameter + - Description + + * - ``field`` + - An expression that specifies the field to update. + + **Data Type:** ``Expression>`` + + * - ``value`` + - The value to set the field to. + + **Data Type:** ``TField`` + +To update the value of the field to a specified value, but only if the specified value +is *less than* the current value of the field, call the ``Builders.Update.Min()`` +method. This method accepts the following parameters: + +.. list-table:: + :widths: 30 70 + :header-rows: 1 + + * - Parameter + - Description + + * - ``field`` + - An expression that specifies the field to update. + + **Data Type:** ``Expression>`` + + * - ``value`` + - The value to set the field to. + + **Data Type:** ``TField`` + +Set on Insert +------------- + +To set the value of a field only if the document was upserted by the same operation, call the +``Builders.Update.SetOnInsert()`` method. This method accepts the following parameters: + +.. list-table:: + :widths: 30 70 + :header-rows: 1 + + * - Parameter + - Description + + * - ``field`` + - An expression that specifies the field to update. + + **Data Type:** ``Expression>`` + + * - ``value`` + - The value to set the field to. + + **Data Type:** ``TField`` + +Set the Current Date +-------------------- + +To set the value of a field to the current date and time, call the +``Builders.Update.CurrentDate()`` method. This method accepts the following parameters: + +.. list-table:: + :widths: 30 70 + :header-rows: 1 + + * - Parameter + - Description + + * - ``field`` + - An expression that specifies the field to update. + + **Data Type:** ``Expression>`` + + * - ``type`` + - The format of the date and time, defined in the ``UpdateDefinitionCurrentDateType`` + enum. The default value is ``null``. + + **Data Type:** `UpdateDefinitionCurrentDateType? <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.UpdateDefinitionCurrentDateType.html>`__ + +Unset a Field +------------- + +To remove a field from a document, call the ``Builders.Update.Unset()`` method. This +method accepts the following parameter: + +.. list-table:: + :widths: 30 70 + :header-rows: 1 + + * - Parameter + - Description + + * - ``field`` + - An expression that specifies the field to remove. + + **Data Type:** ``Expression>`` + +API Documentation +----------------- + +For more information about any of the methods discussed in this +guide, see the following API documentation: + +- `Builders.Update.Inc() <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.UpdateDefinitionBuilder-1.Inc.html>`__ +- `Builders.Update.Mul() <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.UpdateDefinitionBuilder-1.Mul.html>`__ +- `Builders.Update.Rename() <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.UpdateDefinitionBuilder-1.Rename.html>`__ +- `Builders.Update.Set() <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.UpdateDefinitionBuilder-1.Set.html>`__ +- `Builders.Update.Max() <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.UpdateDefinitionBuilder-1.Max.html>`__ +- `Builders.Update.Min() <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.UpdateDefinitionBuilder-1.Min.html>`__ +- `Builders.Update.SetOnInsert() <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.UpdateDefinitionBuilder-1.SetOnInsert.html>`__ +- `Builders.Update.CurrentDate() <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.UpdateDefinitionBuilder-1.CurrentDate.html>`__ +- `Builders.Update.Unset() <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.UpdateDefinitionBuilder-1.Unset.html>`__ \ No newline at end of file diff --git a/source/includes/page-templates/update/update.rst b/source/includes/page-templates/update/update.rst new file mode 100644 index 00000000..49741885 --- /dev/null +++ b/source/includes/page-templates/update/update.rst @@ -0,0 +1,264 @@ +Overview +-------- + +In this guide, you can learn how to use the {+driver-long+} to update +values in |single-or-multiple|. + +The {+driver-short+} provides the following methods to update values: + +- |sync-method|: Updates one or more fields in |single-or-multiple|. +- |async-method|: The asynchronous version of |sync-method|. + +The following sections describe these methods in more detail. + +.. include:: /includes/method-overloads.rst + +.. include:: /includes/atlas-sample-data.rst + +Methods and Parameters +---------------------- + +The |sync-method| and |async-method| methods accept the following parameters: + +.. list-table:: + :widths: 30 70 + :header-rows: 1 + + * - Parameter + - Description + + * - ``filter`` + - An instance of the ``FilterDefinition`` class that specifies the |document-or-documents| + to update. + To learn how to create a query filter, see :ref:`csharp-specify-query`. + + **Data Type:** `FilterDefinition <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.FilterDefinition-1.html>`__ + + * - ``update`` + - An instance of the ``UpdateDefinition`` class. This object specifies the kind of update + operation, the fields to update, and the new value for each field. To learn how to + create an ``UpdateDefinition`` object, see |fields-link| and |arrays-link|. + + **Data Type:** `UpdateDefinition <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.UpdateDefinition-1.html>`__ + + * - ``options`` + - *Optional.* An instance of the ``UpdateOptions`` class that specifies the + configuration for the update operation. The default value is ``null``. For a list + of available options, see :ref:`csharp-update-options`. + + **Data Type:** `UpdateOptions <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.UpdateOptions.html>`__ + + * - ``cancellationToken`` + - *Optional.* A token that you can use to cancel the operation. + + **Data type**: ``CancellationToken`` + +Update Multiple Values +---------------------- + +The |sync-method| and |async-method| methods each accept only one +``UpdateDefinition`` object. The following sections describe how +to update multiple values in a single method call. + +Combined Update Definitions +~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The ``Builders.Update.Combine()`` method lets you combine multiple ``UpdateDefinition`` +objects. This method accepts the following parameter: + +.. list-table:: + :widths: 30 70 + :header-rows: 1 + + * - Parameter + - Description + + * - ``updates`` + - An array of update definitions to combine. + + **Data Type:** ``UpdateDefinition[]`` + +The ``Combine()`` method returns a single ``UpdateDefinition`` object that defines +multiple update operations. + +The following code example uses the ``Combine()`` method to combine a +:manual:`$set ` operation and an +:manual:`$unset ` +operation: + +|combine-code-example-tabs| + +Update Pipelines +~~~~~~~~~~~~~~~~ + +If your application connects to {+mdb-server+} 4.2 or later, you can join +a sequence of update operations into a single +:manual:`aggregation pipeline. ` + +To create an update pipeline, call the ``Builders.Update.Pipeline()`` method. This method +accepts the following parameter: + +.. list-table:: + :widths: 30 70 + :header-rows: 1 + + * - Parameter + - Description + + * - ``pipeline`` + - A ``PipelineDefinition`` instance that represents the update pipeline. To create + a ``PipelineDefinition`` object, create a BSON document for each update operation you + want to perform, then pass these documents to the ``PipelineDefinition.Create()`` method. + + **Data Type:** ``PipelineDefinition`` + +The ``Pipeline()`` method returns a single ``UpdateDefinition`` object that defines +multiple aggregation stages. + +The following code example uses the ``Pipeline()`` method to combine a +:manual:`$set ` operation and an +:manual:`$unset ` +operation: + +|pipeline-code-example-tabs| + +.. note:: Unsupported Operations + + Update pipelines don't support all update operations, but they do support certain + aggregation stages not found in other update definitions. For a list of + update operations supported by pipelines, see + :manual:`Updates with Aggregation Pipeline ` + in the {+mdb-server+} manual. + +.. _csharp-update-options: + +Configuration Options +--------------------- + +The |sync-method| and |async-method| methods optionally accept an +``UpdateOptions`` object as a parameter. You can use this argument to configure the +update operation. + +The ``UpdateOptions`` class contains the following properties: + +.. list-table:: + :widths: 30 70 + :header-rows: 1 + + * - Property + - Description + + * - ``ArrayFilters`` + - Specifies which array elements to modify for an update operation on an array field. + See :manual:`the {+mdb-server+} manual` + for more information. + + **Data Type:** IEnumerable<`ArrayFilterDefinition <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.ArrayFilterDefinition.html>`__> + + * - ``BypassDocumentValidation`` + - Specifies whether the update operation bypasses document validation. This lets you + update documents that don't meet the schema validation requirements, if any + exist. See :manual:`the {+mdb-server+} manual` + for more information on schema validation. + + **Data Type:** ``bool?`` + + * - ``Collation`` + - Specifies the kind of language collation to use when sorting + results. See :manual:`the {+mdb-server+} manual` + for more information on collation. + + **Data Type:** `Collation <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.Collation.html>`__ + + * - ``Comment`` + - Gets or sets the user-provided comment for the operation. + See :manual:`the {+mdb-server+} manual` + for more information. + + **Data Type:** `BsonValue <{+new-api-root+}/MongoDB.Bson/MongoDB.Bson.BsonValue.html>`__ + + * - ``Hint`` + - Gets or sets the index to use to scan for documents. + See :manual:`the {+mdb-server+} manual` + for more information. + + **Data Type:** `BsonValue <{+new-api-root+}/MongoDB.Bson/MongoDB.Bson.BsonValue.html>`__ + + * - ``IsUpsert`` + - Specifies whether the update operation performs an upsert operation if no + documents match the query filter. + See :manual:`the {+mdb-server+} manual ` + for more information. + + **Data Type:** ``bool`` + + * - ``Let`` + - Gets or sets the let document. + See :manual:`the {+mdb-server+} manual ` + for more information. + + **Data Type:** `BsonDocument <{+new-api-root+}/MongoDB.Bson/MongoDB.Bson.BsonDocument.html>`__ + +Return Value +------------ + +The |sync-method| method returns an ``UpdateResult``, and the |async-method| +method returns a ``Task`` object. +The ``UpdateResult`` class contains the following properties: + +.. list-table:: + :widths: 30 70 + :header-rows: 1 + + * - Property + - Description + + * - ``IsAcknowledged`` + - Indicates whether the update operation was acknowledged by MongoDB. + + **Data Type:** ``bool`` + + * - ``IsModifiedCountAvailable`` + - Indicates whether you can read the count of update records on the + ``UpdateResult``. + + **Data Type:** ``bool`` + + * - ``MatchedCount`` + - The number of documents that matched the query filter, regardless of + whether one was updated. + + **Data Type:** ``long`` + + * - ``ModifiedCount`` + - The number of documents updated by the update operation. + + **Data Type:** ``long`` + + * - ``UpsertedId`` + - The ID of the document that was upserted in the database, if the driver + performed an upsert. + + **Data Type:** `BsonValue <{+new-api-root+}/MongoDB.Bson/MongoDB.Bson.BsonValue.html>`__ + +Additional Information +---------------------- + +|instruqt-lab-instructions| + +For runnable examples of the update operations, see the |usage-examples-link| page. + +To learn more about creating query filters, see the :ref:`csharp-specify-query` guide. + +API Documentation +~~~~~~~~~~~~~~~~~ + +For more information about any of the methods or types discussed in this +guide, see the following API documentation: + +- |sync-api-link| +- |async-api-link| +- `UpdateOptions <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.UpdateOptions.html>`__ +- `UpdateResult <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.UpdateResult.html>`__ + +|instruqt-lab-component| \ No newline at end of file diff --git a/source/includes/update-arrays-positional-operator-note.rst b/source/includes/update-arrays-positional-operator-note.rst new file mode 100644 index 00000000..6f32e4ed --- /dev/null +++ b/source/includes/update-arrays-positional-operator-note.rst @@ -0,0 +1,3 @@ +.. note:: + + To use the positional operator, the array field must be part of the query filter. \ No newline at end of file diff --git a/source/includes/update-many/allpositional-linq-code-intro.rst b/source/includes/update-many/allpositional-linq-code-intro.rst new file mode 100644 index 00000000..64c05f28 --- /dev/null +++ b/source/includes/update-many/allpositional-linq-code-intro.rst @@ -0,0 +1,3 @@ +The following example uses the ``Set()`` and ``AllElements()`` methods +to update the ``Score`` property of all ``GradeEntry`` objects in the ``Grades`` array +to 100 in all matching documents. \ No newline at end of file diff --git a/source/includes/update-many/allpositional-operator-code-intro.rst b/source/includes/update-many/allpositional-operator-code-intro.rst new file mode 100644 index 00000000..623fc75b --- /dev/null +++ b/source/includes/update-many/allpositional-operator-code-intro.rst @@ -0,0 +1,3 @@ +The following example uses the ``Set()`` method and the all-positional operator +to update the ``Score`` property of all ``GradeEntry`` objects in the ``Grades`` array +to 100 in all matching documents. \ No newline at end of file diff --git a/source/includes/update-many/filteredpositional-linq-code-intro.rst b/source/includes/update-many/filteredpositional-linq-code-intro.rst new file mode 100644 index 00000000..fe4d031f --- /dev/null +++ b/source/includes/update-many/filteredpositional-linq-code-intro.rst @@ -0,0 +1,3 @@ +The following example uses the ``Set()`` and ``AllMatchingElements()`` methods +to update the ``Score`` property of all matching +``GradeEntry`` objects in the ``Grades`` array to 100 in all matching documents. \ No newline at end of file diff --git a/source/includes/update-many/filteredpositional-operator-code-intro.rst b/source/includes/update-many/filteredpositional-operator-code-intro.rst new file mode 100644 index 00000000..98823213 --- /dev/null +++ b/source/includes/update-many/filteredpositional-operator-code-intro.rst @@ -0,0 +1,3 @@ +The following example uses the ``Set()`` method and the filtered positional operator +to update the ``Score`` property of all matching +``GradeEntry`` objects in the ``Grades`` array to 100 in all matching documents. \ No newline at end of file diff --git a/source/includes/update-many/positional-linq-code-intro.rst b/source/includes/update-many/positional-linq-code-intro.rst new file mode 100644 index 00000000..5985bacb --- /dev/null +++ b/source/includes/update-many/positional-linq-code-intro.rst @@ -0,0 +1,5 @@ +The following example uses the ``Set()`` and ``FirstMatchingElement()`` methods to +update the ``Grades`` array in all matching documents. First, +it finds *only the first* ``GradeEntry`` object in the ``Grades`` array where the +``Grade`` property has the value ``"A"``. Then, it updates the ``Score`` property of +the first matching ``GradeEntry`` object to 100. \ No newline at end of file diff --git a/source/includes/update-many/positional-operator-code-intro.rst b/source/includes/update-many/positional-operator-code-intro.rst new file mode 100644 index 00000000..830f407a --- /dev/null +++ b/source/includes/update-many/positional-operator-code-intro.rst @@ -0,0 +1,5 @@ +The following example uses the ``Set()`` method and the positional operator to +update the ``Grades`` array in all matching documents. First, +it finds *only the first* ``GradeEntry`` object in the ``Grades`` array where the ``Grade`` +property has the value ``"A"``. Then, it updates the ``Score`` property of the first matching +``GradeEntry`` object to 100. \ No newline at end of file diff --git a/source/includes/update-one/allpositional-linq-code-intro.rst b/source/includes/update-one/allpositional-linq-code-intro.rst new file mode 100644 index 00000000..13cdf68e --- /dev/null +++ b/source/includes/update-one/allpositional-linq-code-intro.rst @@ -0,0 +1,3 @@ +The following example uses the ``Set()`` and ``AllElements()`` methods +to update the ``Score`` property of all ``GradeEntry`` objects in the ``Grades`` array +to 100 in the matching document. \ No newline at end of file diff --git a/source/includes/update-one/allpositional-operator-code-intro.rst b/source/includes/update-one/allpositional-operator-code-intro.rst new file mode 100644 index 00000000..2c340a4d --- /dev/null +++ b/source/includes/update-one/allpositional-operator-code-intro.rst @@ -0,0 +1,3 @@ +The following example uses the ``Set()`` method and the all-positional operator +to update the ``Score`` property of all ``GradeEntry`` objects in the ``Grades`` array +to 100 in the matching document. \ No newline at end of file diff --git a/source/includes/update-one/filteredpositional-linq-code-intro.rst b/source/includes/update-one/filteredpositional-linq-code-intro.rst new file mode 100644 index 00000000..a12559d6 --- /dev/null +++ b/source/includes/update-one/filteredpositional-linq-code-intro.rst @@ -0,0 +1,3 @@ +The following example uses the ``Set()`` and ``AllMatchingElements()`` methods +to update the ``Score`` property of all matching +``GradeEntry`` objects in the ``Grades`` array to 100 in the matching document. \ No newline at end of file diff --git a/source/includes/update-one/filteredpositional-operator-code-intro.rst b/source/includes/update-one/filteredpositional-operator-code-intro.rst new file mode 100644 index 00000000..cd2f4189 --- /dev/null +++ b/source/includes/update-one/filteredpositional-operator-code-intro.rst @@ -0,0 +1,3 @@ +The following example uses the ``Set()`` method and the filtered positional operator +to update the ``Score`` property of all matching +``GradeEntry`` objects in the ``Grades`` array to 100 in the matching document. \ No newline at end of file diff --git a/source/includes/update-one/positional-linq-code-intro.rst b/source/includes/update-one/positional-linq-code-intro.rst new file mode 100644 index 00000000..2d173256 --- /dev/null +++ b/source/includes/update-one/positional-linq-code-intro.rst @@ -0,0 +1,5 @@ +The following example uses the ``Set()`` and ``FirstMatchingElement()`` methods to +update the ``Grades`` array in the matching document. First, +it finds *only the first* ``GradeEntry`` object in the ``Grades`` array where the +``Grade`` property has the value ``"A"``. Then, it updates the ``Score`` property of +the first matching ``GradeEntry`` object to 100. \ No newline at end of file diff --git a/source/includes/update-one/positional-operator-code-intro.rst b/source/includes/update-one/positional-operator-code-intro.rst new file mode 100644 index 00000000..57579dab --- /dev/null +++ b/source/includes/update-one/positional-operator-code-intro.rst @@ -0,0 +1,5 @@ +The following example uses the ``Set()`` method and the positional operator to +update the ``Grades`` array in the matching document. First, +it finds *only the first* ``GradeEntry`` object in the ``Grades`` array where the ``Grade`` +property has the value ``"A"``. Then, it updates the ``Score`` property of the first matching +``GradeEntry`` object to 100. \ No newline at end of file diff --git a/source/quick-reference.txt b/source/quick-reference.txt index 6c85abc9..dc82f454 100644 --- a/source/quick-reference.txt +++ b/source/quick-reference.txt @@ -180,8 +180,8 @@ their related reference and API documentation. * - | **Update a Document** | | `API Documentation <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.IMongoCollection-1.UpdateOne.html>`__ - | :ref:`Usage Example ` - | :ref:`Fundamentals ` + | :ref:`Usage Example ` + | :ref:`Fundamentals ` - .. code-block:: csharp :copyable: true @@ -197,8 +197,8 @@ their related reference and API documentation. * - | **Update a Document (Async)** | | `API Documentation <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.IMongoCollection-1.UpdateOneAsync.html>`__ - | :ref:`Usage Example ` - | :ref:`Fundamentals ` + | :ref:`Usage Example ` + | :ref:`Fundamentals ` - .. code-block:: csharp :copyable: true @@ -214,8 +214,8 @@ their related reference and API documentation. * - | **Update Multiple Documents** | | `API Documentation <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.IMongoCollection-1.UpdateMany.html>`__ - | :ref:`Usage Example ` - | :ref:`Fundamentals ` + | :ref:`Usage Example ` + | :ref:`Fundamentals ` - .. code-block:: csharp :copyable: true @@ -231,8 +231,8 @@ their related reference and API documentation. * - | **Update Multiple Documents (Async)** | | `API Documentation <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.IMongoCollection-1.UpdateManyAsync.html>`__ - | :ref:`Usage Example ` - | :ref:`Fundamentals ` + | :ref:`Usage Example ` + | :ref:`Fundamentals ` - .. code-block:: csharp :copyable: true @@ -248,7 +248,8 @@ their related reference and API documentation. * - | **Update an Array in a Document** | | `API Documentation <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.IMongoCollection-1.UpdateOne.html>`__ - | :ref:`Fundamentals ` + | :ref:`Fundamentals (Update One) ` + | :ref:`Fundamentals (Update Many) ` - .. code-block:: csharp :copyable: true diff --git a/source/upgrade/v2.txt b/source/upgrade/v2.txt index e999c685..91c30e39 100644 --- a/source/upgrade/v2.txt +++ b/source/upgrade/v2.txt @@ -135,6 +135,12 @@ Version 2.19.0 Breaking Changes clientSettings.LinqProvider = LinqProvider.V2; var client = new MongoClient(clientSettings); + If your application uses the LINQ3 provider, you can't use ``-1`` to represent the + :manual:`positional operator ` + when updating an array. To learn how to use the positional operator, see + :ref:`Update One ` and + :ref:`Update Many `. + Version 2.14.0 Breaking Changes ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/source/usage-examples/updateMany.txt b/source/usage-examples/updateMany.txt index 65a2763e..7c1b5203 100644 --- a/source/usage-examples/updateMany.txt +++ b/source/usage-examples/updateMany.txt @@ -1,4 +1,4 @@ -.. _csharp-update-many: +.. _csharp-examples-update-many: ===================== Update Many Documents @@ -73,7 +73,7 @@ Running either of the preceding full examples prints the following results: More Information ---------------- -To learn more about updating documents, see the :ref:`csharp-change-guide` guide. +To learn more about updating documents, see the :ref:`csharp-update-many` guide. To learn more about using builders, see :ref:`csharp-builders`. diff --git a/source/usage-examples/updateOne.txt b/source/usage-examples/updateOne.txt index eecfb94b..df6c799a 100644 --- a/source/usage-examples/updateOne.txt +++ b/source/usage-examples/updateOne.txt @@ -1,4 +1,4 @@ -.. _csharp-update-one: +.. _csharp-examples-update-one: ================= Update a Document @@ -86,7 +86,7 @@ writes the following to the console: More Information ---------------- -To learn more about updating documents, see the :ref:`csharp-change-guide` guide. +To learn more about updating documents, see the :ref:`csharp-update-one` guide. To learn more about using builders, see :ref:`csharp-builders`.