{"id":101954,"date":"2024-04-29T21:10:35","date_gmt":"2024-04-29T21:10:35","guid":{"rendered":"https:\/\/www.red-gate.com\/simple-talk\/?p=101954"},"modified":"2024-11-14T22:21:43","modified_gmt":"2024-11-14T22:21:43","slug":"updating-documents-in-mongodb","status":"publish","type":"post","link":"https:\/\/www.red-gate.com\/simple-talk\/databases\/nosql\/mongodb\/updating-documents-in-mongodb\/","title":{"rendered":"Updating Documents in MongoDB"},"content":{"rendered":"<p><strong>This article is part of Robert Sheldon's continuing series on Mongo DB. To see all of the items in the series, <a href=\"https:\/\/www.red-gate.com\/simple-talk\/collections\/robert-sheldon-ongoing-mongodb-primer\/\">click here<\/a>.<\/strong><\/p>\n\n<p>In the previous articles this series, I demonstrated various ways to retrieve document data from a MongoDB database, using both MongoDB Shell and MongoDB Compass. In this article, my focus shifts from retrieving data to updating data, which is an essential skill to have when working with MongoDB. Whether you access the data directly in a MongoDB database or build applications that rely on the data, you should have a good foundation in how to modify a collection\u2019s documents. This article can help you build that foundation.<\/p>\n<p>MongoDB provides multiple methods for modifying the documents in a collection. In this article, I focus on two of those methods: <code>updateOne<\/code> and <code>updateMany<\/code>. The methods are fairly similar to each other except that, as their names suggest, the <code>updateOne<\/code> method can update only one document at a time, while the <code>updateMany<\/code> method can modify any number of documents.<\/p>\n<p>In this article, I demonstrate how to build update statements that use these two methods to modify data. The examples are based on MongoDB Shell, rather than on how the methods might be used in a programming language such as Java or Python. On the surface, the <code>updateOne<\/code> and <code>updateMany<\/code> methods might seem fairly basic, but when you start digging deeper into them, you\u2019ll find that they\u2019re not quite as straightforward as they appear.<\/p>\n<p>This article takes you through the basics of using these methods to modify document data. As with most MongoDB topics, covering every aspect of the two methods requires more than a single article. However, I tried to provide you with the most important information so you can start using them in your own projects.<\/p>\n<p>Note: For the examples in this article, I used the same MongoDB Atlas and MongoDB Compass environments I used for the previous articles in this series. Refer to the first article for more specifics about setting up these environments. If you want to try out the examples in this article, you should create the <code>hr<\/code> database and <code>employees<\/code> collection in that database. Each section provides the test data you\u2019ll need to try out those examples.<\/p>\n<h2>Updating documents in a MongoDB collection<\/h2>\n<p>The <code>updateOne<\/code> and <code>updateMany<\/code> methods are two of the most common methods used to update data in MongoDB. You can incorporate either one into a statement that you can then run in MongoDB Shell. The statement\u2019s basic syntax is essentially the same for both methods, except for the method name. For example, the following syntax shows the elements that make up an <code>updateOne<\/code> statement:<\/p>\n<pre class=\"lang:none theme:none \">db.collection.updateOne( { filter }, { update }, { options } );<\/pre>\n<p>The syntax might vary when used in other programming languages\u2014as opposed to MongoDB Shell\u2014but the basic concepts are much the same. In this case, the <code>updateOne<\/code> statement is made up of the following components:<\/p>\n<ul>\n<li><strong>db.<\/strong> System variable for referencing the current database and accessing the properties and methods available to the database object.<\/li>\n<li><strong><em>collection<\/em>.<\/strong> Placeholder for the target collection. For this article, we will be using the <code>employees<\/code> collection.<\/li>\n<li><strong>updateOne.<\/strong> A method available to the collection object for updating a single document in the specified collection.<\/li>\n<li><strong><em>filter<\/em>.<\/strong> Placeholder for the selection criteria that determine which document to update. This is similar to the filter used in a <code>find<\/code> statement. If <code><em>filter<\/em><\/code> returns more than one document, MongoDB applies the update only to the first document returned from the collection. An empty document (<code>{}<\/code>) means that <code><em>filter<\/em><\/code> returns all documents in the collection, although MongoDB still applies the update only to the first returned document. Some MongoDB documentation refers to this element as <code><em>query<\/em><\/code>, rather than <code><em>filter<\/em><\/code>.<\/li>\n<li><strong><em>update<\/em>.<\/strong> Placeholder for the modifications that should be applied to the documents returned by <code><em>filter<\/em><\/code>. The above syntax shows this section enclosed in curly brackets, which indicate that you should pass in your update definition as an embedded document. However, you can instead pass in your argument as a limited aggregation pipeline, in which case, the argument is enclosed in square brackets.<\/li>\n<li><strong><em>options<\/em>.<\/strong> Placeholder for one or more optional settings that can be included in an <code>updateOne<\/code> statement to better refine the query.<\/li>\n<\/ul>\n<p>A statement that is based on an <code>updateMany<\/code> method works much the same way as the <code>updateOne<\/code> method. The only variation in the basic syntax is the method name:<\/p>\n<pre class=\"lang:none theme:none \">db.collection.updateMany( { filter }, { update }, { options } );<\/pre>\n<p>The main difference between the <code>updateOne<\/code> and <code>updateMany<\/code> methods, other than their names, is the <code><em>filter<\/em><\/code> element. With the <code>updateOne<\/code> method, the update is applied only to the first document returned from the collection, no matter how many documents that <code><em>filter<\/em><\/code> returns. With the <code>updateMany<\/code> method, the update is applied to all documents that <code><em>filter<\/em><\/code> returns.<\/p>\n<p>You\u2019ll be able to get a better sense of how these two methods work and the differences between them as we go through the examples in this article. You\u2019ll also see a couple of the options in action so you can get a better sense of how they work. In the meantime, you can find more information about the <code>updateOne<\/code> and <code>updateMany<\/code> methods, as well as other methods for updating data, in the MongoDB topic <a href=\"https:\/\/www.mongodb.com\/docs\/manual\/reference\/update-methods\/\">Update Methods<\/a>.<\/p>\n<h2>Performing a basic update<\/h2>\n<p>To help you get started with the <code>updateOne<\/code> and <code>updateMany<\/code> methods, we\u2019ll begin with a couple basic examples of how to modify documents in a collection. For this article, we\u2019ll be using the version of MongoDB Shell embedded in the MongoDB Compass GUI. In this way, we can view our results in the main Compass interface as we update the data MongoDB Shell, making it easier to see what has changed.<\/p>\n<p>If you plan to try out these examples for yourself, make sure to first create the <code>hr<\/code> database and <code>employees<\/code> collection. You should then open the collection in the main Compass window so you can easily see your results as you work through the examples.<\/p>\n<p>After you\u2019ve set up your database and collection, go to MongoDB Shell and run the following <code>use<\/code> statement to change the context to the <code>hr<\/code> database:<\/p>\n<pre class=\"lang:none theme:none\">use hr<\/pre>\n<p>Next, you\u2019ll need to add several documents to the collection so you have something to update. For this, you can use an <code>insertMany<\/code> method. The method is available to the collection object for adding multiple documents to a collection. The following statement uses the method to add three documents to the <code>employees<\/code> collection:<\/p>\n<pre class=\"lang:none theme:none\">db.employees.insertMany([\n  { \"_id\": 101, \"name\": \"Drew\", \"title\": \"Senior Developer\", \"department\": \"Development\" },\n  { \"_id\": 102, \"name\": \"Parker\", \"title\": \"Data Scientist\", \"department\": \"Development\" },\n  { \"_id\": 103, \"name\": \"Kerry\", \"title\": \"Marketing Manager\", \"department\": \"Marketing\" }\n]);<\/pre>\n<p>The documents are passed into the <code>insertMany<\/code> method as an array of embedded documents. Although these are very simple documents, they\u2019re enough to demonstrate how to update data.<\/p>\n<p>To run the <code>insertMany<\/code> statement, copy and paste it to the MongoDB Shell command prompt and then press Enter. MongoDB should return a message indicating that the three documents have been added. Next, go to the <strong>Documents<\/strong> tab of the main Compass window and click the refresh button in the tab\u2019s upper right corner. The tab should now display the three documents, as shown in the following figure.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"2394\" height=\"1648\" class=\"wp-image-101955\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2024\/03\/word-image-101954-1.png\" \/><\/p>\n<p>With the data in place, you\u2019re now ready to try out your first update statement. In the following example, the <code>updateOne<\/code> method identifies the target document and changes the value of the <code>title<\/code> field to <code>Brand<\/code> <code>Manager<\/code>:<\/p>\n<pre class=\"lang:none theme:none\">db.employees.updateOne(\n  { \"_id\" : 103 },\n  { $set: { \"title\" : \"Brand Manager\" } }\n);<\/pre>\n<p>The statement includes two embedded documents, which define the method\u2019s <code><em>filter<\/em><\/code> and <code><em>update<\/em><\/code> elements, respectively:<\/p>\n<ul>\n<li>The <code><em>filter<\/em><\/code> element specifies that only the document with an <code>_id<\/code> value of <code>103<\/code> should be updated.<\/li>\n<li>The <code><em>update<\/em><\/code> element uses the <code>$set<\/code> operator to assign a new value to a field. In this case, the operator sets the value of the <code>title<\/code> field to <code>Brand<\/code> <code>Manager<\/code>. The field name and its value are enclosed in curly brackets and separated by a colon.<\/li>\n<\/ul>\n<p>When you run this statement, MongoDB Shell returns the following message, which indicates that one document matched the <code><em>filter<\/em><\/code> criteria and one document was modified:<\/p>\n<pre class=\"lang:none theme:none\">{\n  acknowledged: true,\n  insertedId: null,\n  matchedCount: 1,\n  modifiedCount: 1,\n  upsertedCount: 0\n}<\/pre>\n<p>If you return to the <strong>Documents<\/strong> tab of the main window and click the refresh button, the Compass GUI should now display the following results, which show that the <code>title<\/code> value in the third document has been updated.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"794\" height=\"758\" class=\"wp-image-101956\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2024\/03\/word-image-101954-2.png\" \/><\/p>\n<p>Now let\u2019s look at an example that uses the <code>updateMany<\/code> method to modify documents. The following statement changes the value of the <code>department<\/code> field to <code>R&amp;D<\/code> in the target documents:<\/p>\n<pre class=\"lang:none theme:none\">db.employees.updateMany(\n  { \"department\" : \"Development\" },\n  { $set: { \"department\" : \"R&amp;D\" } }\n);<\/pre>\n<p>As with the previous example, the statement includes two embedded documents for defining the <code><em>filter<\/em><\/code> and <code><em>update<\/em><\/code> elements:<\/p>\n<ul>\n<li>The <code><em>filter<\/em><\/code> element specifies that only documents with a <code>department<\/code> value of <code>Development<\/code> should be updated.<\/li>\n<li>The <code><em>update<\/em><\/code> element uses the <code>$set<\/code> operator to set the <code>department<\/code> value to <code>R&amp;D<\/code>.<\/li>\n<\/ul>\n<p>When you run this statement, MongoDB Shell returns the following message, which indicates that two documents match the search criteria and two documents have been modified:<\/p>\n<pre class=\"lang:none theme:none\">{\n  acknowledged: true,\n  insertedId: null,\n  matchedCount: 2,\n  modifiedCount: 2,\n  upsertedCount: 0\n}<\/pre>\n<p>If you once again refresh the <strong>Documents<\/strong> tab of the main window, Compass should now display the following results, which show that the <code>department<\/code> value in the first two documents has been updated.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"824\" height=\"760\" class=\"wp-image-101957\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2024\/03\/word-image-101954-3.png\" \/><\/p>\n<p>As you can see, using the <code>updateOne<\/code> and <code>updateMany<\/code> methods to perform basic modifications on a document is fairly straightforward, and the two methods work much the same. You must first define the <code><em>filter<\/em><\/code> element, followed by the <code><em>update<\/em><\/code> element. That said, there is much more you can do with both of these methods.<\/p>\n<h2>Performing an Upsert<\/h2>\n<p>As I mentioned earlier in the article, the <code>updateOne<\/code> and <code>updateMany<\/code> methods let you specify optional settings to better refine your query. One of these options is <code>upsert<\/code>, which controls how an <code>updateOne<\/code> or <code>updateMany<\/code> statement behaves if no documents match the <code><em>filter<\/em><\/code> criteria.<\/p>\n<p>The <code>upsert<\/code> option takes a Boolean value, either <code>true<\/code> or <code>false<\/code>. When the option is set to <code>true<\/code>, the statement performs one of the following actions:<\/p>\n<ul>\n<li>If <code><em>filter<\/em><\/code> returns a match, the statement updates the target document or documents.<\/li>\n<li>If <code><em>filter<\/em><\/code> returns no matches, the statement inserts a new document, based on the <code><em>filter<\/em><\/code> and <code><em>update<\/em><\/code> elements.<\/li>\n<\/ul>\n<p>If the <code>upsert<\/code> option is instead set to <code>false<\/code>, the statement does not insert a new document into the collection, even if <code><em>filter<\/em><\/code> returns no matches. This is the default setting and how an update statement behaves when the option is not specified.<\/p>\n<p>Before we look at an example that uses the <code>upsert<\/code> option, let\u2019s delete the existing documents in the <code>employees<\/code> collection so we\u2019re starting with a clean slate. You can delete all the documents at once by running the following <code>deleteMany<\/code> statement:<\/p>\n<pre class=\"lang:none theme:none\">db.employees.deleteMany({});<\/pre>\n<p>Because the <code>deleteMany<\/code> statement does not specify a <code><em>filter<\/em><\/code> criteria\u2014instead using only an empty set of curly brackets\u2014the statement will delete all documents in the collection. This is a handy statement to remember when you\u2019re learning about MongoDB or want to clean up your development or test environments. However, use extreme caution when using this statement in a production environment.<\/p>\n<p>After you delete the collection\u2019s documents, you can run the following <code>insertMany<\/code> statement to add the original documents back into the collection:<\/p>\n<pre class=\"lang:none theme:none\">db.employees.insertMany([\n  { \"_id\": 101, \"name\": \"Drew\", \"title\": \"Senior Developer\", \"department\": \"Development\" },\n  { \"_id\": 102, \"name\": \"Parker\", \"title\": \"Data Scientist\", \"department\": \"Development\" },\n  { \"_id\": 103, \"name\": \"Kerry\", \"title\": \"Marketing Manager\", \"department\": \"Marketing\" }\n]);<\/pre>\n<p>Now let\u2019s try out the <code>upsert<\/code> option when updating a document. The following <code>updateOne<\/code> statement attempts to update a document with an <code>_id<\/code> value of <code>104<\/code>:<\/p>\n<pre class=\"lang:none theme:none\">db.employees.updateOne(\n  { \"_id\" : 104 },\n  { $set: { \"name\": \"Casey\", \"title\": \"Copy Writer\", \"department\": \"Marketing\" } },\n  { upsert: true }\n);<\/pre>\n<p>Unlike the previous examples, the method now includes three embedded documents:<\/p>\n<ul>\n<li>The <code><em>filter<\/em><\/code> element specifies that only the document with an <code>_id<\/code> value of <code>104<\/code> should be updated.<\/li>\n<li>The <code><em>update<\/em><\/code> element uses the <code>$set<\/code> operator to set the <code>name<\/code>, <code>title<\/code> , and <code>department<\/code> fields to the values <code>Casey<\/code>, <code>Copy<\/code> <code>Writer<\/code>, and <code>Marketing<\/code>, respectively.<\/li>\n<li>The <code>upsert<\/code> element sets the <code>upsert<\/code> option to <code>true<\/code>. Notice that the option is added as an embedded document, just like the <code><em>filter<\/em><\/code> and <code><em>update<\/em><\/code> elements.<\/li>\n<\/ul>\n<p>When you run the <code>updateOne<\/code> statement, MongoDB Shell returns the following message:<\/p>\n<pre class=\"lang:none theme:none\">{\n  acknowledged: true,\n  insertedId: 104,\n  matchedCount: 0,\n  modifiedCount: 0,\n  upsertedCount: 1\n}<\/pre>\n<p>The message indicates that one document has been upserted and the ID for that document is <code>104<\/code>. It also indicates that there were no matched documents. If you once again refresh the <strong>Documents<\/strong> tab of the main window, the Compass GUI should display the results shown in the following figure, which now include a fourth document.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"790\" height=\"942\" class=\"wp-image-101958\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2024\/03\/word-image-101954-4.png\" \/><\/p>\n<p>MongoDB added the fourth document to the collection because no documents matched the <code><em>filter<\/em><\/code> criteria in the original query. An <code>updateMany<\/code> statement works much the same way, as shown in the following example:<\/p>\n<pre class=\"lang:none theme:none\">db.employees.updateMany(\n  { \"name\": \"Jesse\", \"title\": \"Senior Developer\" },\n  { $set: { \"department\" : \"R&amp;D\" } },\n  { upsert: true }\n);<\/pre>\n<p>Like the previous example, this statement includes three embedded documents:<\/p>\n<ul>\n<li>The <code><em>filter<\/em><\/code> element specifies that only documents with a <code>name<\/code> value of <code>Jesse<\/code> and a <code>title<\/code> value of <code>Senior<\/code> <code>Developer<\/code> should be updated.<\/li>\n<li>The <code><em>update<\/em><\/code> element uses the <code>$set<\/code> operator to set the <code>department<\/code> value to <code>R&amp;D<\/code>.<\/li>\n<li>The <code>upsert<\/code> element sets the <code>upsert<\/code> option to <code>true<\/code>.<\/li>\n<\/ul>\n<p>When you run the <code>updateMany<\/code> statement, MongoDB Shell returns the following message:<\/p>\n<pre class=\"lang:none theme:none\">{\n  acknowledged: true,\n  insertedId: ObjectId('65de345e261378a0b003c281'),\n  matchedCount: 0,\n  modifiedCount: 0,\n  upsertedCount: 1\n}<\/pre>\n<p>In this case, the message indicates that one document has been upserted and that the document\u2019s ID is a GUID, unlike the simple integers used for the other documents. MongoDB generated the <code>_id<\/code> value automatically because no value had been specified in the <code><em>filter<\/em><\/code> or <code><em>update<\/em><\/code> element. When you refresh the <strong>Documents<\/strong> tab, the Compass GUI now shows the following documents:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"950\" height=\"1118\" class=\"wp-image-101959\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2024\/03\/word-image-101954-5.png\" \/><\/p>\n<p>As you can see, a fifth document was added to the collection, and its <code>_id<\/code> value is a GUID. Because the <code><em>filter<\/em><\/code> element in the <code>updateMany<\/code> statement did not return any matches, MongoDB inserted a new document using the information from the <code><em>filter<\/em><\/code> and <code><em>update<\/em><\/code> elements.<\/p>\n<h2>Updating an embedded document<\/h2>\n<p>In the previous examples, the statements updated simple string fields that required you only to specify the field name and new value. The process works much the same for embedded documents, except that you must qualify the names of the subfields to ensure the data gets modified as expected.<\/p>\n<p>To see how this works, first delete the documents in the <code>employees<\/code> collection, and then run the following <code>insertMany<\/code> statement:<\/p>\n<pre class=\"lang:none theme:none\">db.employees.insertMany([\n  { \"_id\": 101, \n    \"name\": \"Drew\", \n    \"position\": { \n      \"title\": \"Senior Developer\", \n      \"department\": \"Development\" } },\n  { \"_id\": 102, \n    \"name\": \"Parker\", \n    \"position\": { \n      \"title\": \"Data Scientist\", \n      \"department\": \"Development\" } },\n  { \"_id\": 103, \n    \"name\": \"Kerry\", \n    \"position\": { \n      \"title\": \"Marketing Manager\", \n      \"department\": \"Marketing\" } }\n]);<\/pre>\n<p>The statement defines three documents that each contain the <code>position<\/code> field. The field\u2019s value is an embedded document that includes the <code>title<\/code> and <code>department<\/code> subfields. Now let\u2019s try to update one of the subfields, using the following <code>updateOne<\/code> statement:<\/p>\n<pre class=\"lang:none theme:none\">db.employees.updateOne(\n  { \"_id\" : 103 },\n  { $set: { \"position.title\" : \"Brand Manager\" } }\n);<\/pre>\n<p>The <code><em>filter<\/em><\/code> element specifies that only the document with an <code>_id<\/code> value of <code>103<\/code> should be updated. This is followed by the <code><em>update<\/em><\/code> element, which uses the <code>$set<\/code> operator to set the <code>title<\/code> value to <code>Brand<\/code> <code>Manager<\/code>. Notice that you must qualify the subfield name by preceding it with the <code>position<\/code> field name, followed by a period. In this way, MongoDB knows exactly where to find the target subfield.<\/p>\n<p>After you run the statement, you can refresh the <strong>Documents<\/strong> tab to review the results, which are shown in the following figure.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"800\" height=\"742\" class=\"wp-image-101960\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2024\/03\/word-image-101954-6.png\" \/><\/p>\n<p>Notice that the <code>title<\/code> subfield has been updated in the third document. As this example demonstrates, you must qualify the field names in embedded documents when referencing them in an <code><em>update<\/em><\/code> element. This is also true if you specify an embedded field in the <code><em>filter<\/em><\/code> element, as in the following <code>updateMany<\/code> statement:<\/p>\n<pre class=\"lang:none theme:none\">db.employees.updateMany(\n  { \"position.department\" : \"Development\" },\n  { $set: { \"position.department\" : \"R&amp;D\" } }\n);<\/pre>\n<p>This time, the <code><em>filter<\/em><\/code> element specifies that only documents with a <code>position.department<\/code> value of <code>Development<\/code> should be updated. Only two documents meet this criteria. The <code><em>update<\/em><\/code> element then uses the <code>$set<\/code> operator to set their <code>position.department<\/code> value to <code>R&amp;D<\/code>. After you run the statement, you can again refresh the <strong>Documents<\/strong> tab to review the results, which are shown in the following figure.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"816\" height=\"874\" class=\"wp-image-101961\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2024\/03\/word-image-101954-7.png\" \/><\/p>\n<p>That\u2019s all there is to working with embedded documents. That main point to remember is that you need to qualify the field names when they come from an embedded document.<\/p>\n<h2>Updating an array<\/h2>\n<p>Updating an array value is a little trickier than with an embedded document. For this, you\u2019ll need to use the <code>arrayFilters<\/code> option, which I\u2019ll demonstrate shortly. But first, you should again delete the documents in the <code>employees<\/code> collection and this time run the following <code>insertMany<\/code> statement:<\/p>\n<pre class=\"lang:none theme:none\">db.employees.insertMany([\n  { \"_id\": 101, \"name\": \"Drew\", \"skills\": [ \"Java\", \"SQL\", \"Python\", \"PHP\" ] },\n  { \"_id\": 102, \"name\": \"Parker\", \"skills\": [ \"Java\", \"Csharp\", \"Python\", \"R\" ] },\n  { \"_id\": 103, \"name\": \"Kerry\", \"skills\": [ \"Csharp\", \"SQL\", \"Swift\", \"C\" ] }\n]);<\/pre>\n<p>The statement adds three documents to the collection. Each document includes the <code>skills<\/code> array, which contains several string values describing the employee\u2019s skills.<\/p>\n<p>Now let\u2019s look at how to modify the array. Suppose you want to update a skill in one of the documents, in this case, the one with an <code>_id<\/code> value of <code>101<\/code>. Your goal is to change the <code>PHP<\/code> value in the <code>skills<\/code> array to <code>JavaScript<\/code>. For this, you can run the following <code>updateOne<\/code> statement:<\/p>\n<pre class=\"lang:none theme:none\">db.employees.updateOne(\n  { \"_id\": 101 },\n  { $set: { \"skills.$[skill]\": \"JavaScript\" } },\n  { arrayFilters: [ { \"skill\": \"PHP\" } ] }\n);<\/pre>\n<p>As you can see, the <code>updateOne<\/code> method defines three elements:<\/p>\n<ul>\n<li>The <code><em>filter<\/em><\/code> element specifies that only the document with an <code>_id<\/code> value of <code>101<\/code> should be updated.<\/li>\n<li>The <code><em>update<\/em><\/code> element uses the <code>$set<\/code> operator to specify that a value in the <code>skills<\/code> array should be changed to <code>JavaScript<\/code>. The value to be changed is represented by the <code>skill<\/code> variable, which is constructed as an identifier operator. An identifier operator is an element enclosed in square brackets and preceded by a dollar sign, all of which is then tagged onto the array name.<\/li>\n<li>The <code>arrayFilters<\/code> element essentially defines the <code>skill<\/code> variable by assigning the old value, <code>PHP<\/code>, to the variable. In this way, the variable can be used in the <code><em>update<\/em><\/code> element to indicate which value should be changed within the array. Note that the variable (identifier) name must begin with a lowercase letter and can contain only alphanumeric characters.<\/li>\n<\/ul>\n<p>After you run the <code>updateOne<\/code> statement, you can again refresh the <strong>Documents<\/strong> tab and review the results, which are shown in the following figure. As you can see, the original array value, <code>PHP<\/code>, has been replaced with <code>JavaScript<\/code>.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"590\" height=\"786\" class=\"wp-image-101962\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2024\/03\/word-image-101954-8.png\" \/><\/p>\n<p>You can also use the <code>arrayFilters<\/code> option in an <code>updateMany<\/code> statement, once again specifying a variable that identifies the value to be changed. For example, the follow statement updates the documents that contain the value <code>Csharp<\/code> in the <code>skills<\/code> array:<\/p>\n<pre class=\"lang:none theme:none\">db.employees.updateMany(\n  { \"skills\": \"Csharp\" },\n  { $set: { \"skills.$[skill]\": \"C#\" } },\n  { arrayFilters: [ { \"skill\": \"Csharp\" } ] }\n);<\/pre>\n<p>As in the previous example, the statement includes three elements:<\/p>\n<ul>\n<li>The <code><em>filter<\/em><\/code> element specifies that the documents must contain the value <code>Csharp<\/code> in the <code>skills<\/code> array.<\/li>\n<li>The <code><em>update<\/em><\/code> element changes the array value <code>Csharp<\/code> to <code>C#<\/code>, using the <code>skill<\/code> variable to reference the original value.<\/li>\n<li>The <code>arrayFilters<\/code> element assigns the value <code>Csharp<\/code> to the <code>skill<\/code> variable so it can be used in the <code><em>update<\/em><\/code> element.<\/li>\n<\/ul>\n<p>The statement updates two documents. You can confirm this by again refreshing the <strong>Documents<\/strong> tab in the main Compass window. The following figure shows the updated documents.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"686\" height=\"1046\" class=\"wp-image-101963\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2024\/03\/word-image-101954-9.png\" \/><\/p>\n<p>Updating an array value is fairly straightforward once you figure out how an identifier operator works and how to apply the <code>arrayFilters<\/code> option. To this end, you might find it useful to review the MongoDB topic <a href=\"https:\/\/www.mongodb.com\/docs\/manual\/reference\/operator\/update\/positional-filtered\/#mongodb-update-up.---identifier--\">$[&lt;identifier&gt;]<\/a> to get a better sense of how to use both an identifier operator and the <code>arrayFilters<\/code> option.<\/p>\n<h2>Updating with an aggregation pipeline<\/h2>\n<p>The examples up to this point have used an embedded document for the <code><em>update<\/em><\/code> element, which defines the modifications that should be applied to the filtered documents. However, you can instead specify an aggregation pipeline for the <code><em>update<\/em><\/code> element, using any of the following three stages:<\/p>\n<ul>\n<li>The <code>$addFields<\/code> stage (or its alias <code>$set<\/code>)\u2014adds fields to the documents in the pipeline.<\/li>\n<li>The <code>$project<\/code> stage (or its alias <code>$unset<\/code>)\u2014reshapes the fields in the pipeline documents.<\/li>\n<li>The <code>$replaceRoot<\/code> stage (or its alias <code>$replaceWith<\/code>)\u2014replaces each document in the pipeline with the specified embedded document.<\/li>\n<\/ul>\n<p>An aggregation pipeline can provide you with more flexibility when modifying your documents, compared to the statements we\u2019ve created so far. To see how this works, first delete the documents in the <code>employees<\/code> collection, and then run the following <code>insertMany<\/code> statement, which creates three simple documents:<\/p>\n<pre class=\"lang:none theme:none\">db.employees.insertMany([\n  { \"_id\": 101, \"name\": \"Drew\", \"title\": \"Senior Developer\", \"department\": \"Development\" },\n  { \"_id\": 102, \"name\": \"Parker\", \"title\": \"Data Scientist\", \"department\": \"Development\" },\n  { \"_id\": 103, \"name\": \"Kerry\", \"title\": \"Marketing Manager\", \"department\": \"Marketing\" }\n]);<\/pre>\n<p>Next, we\u2019ll create an <code>insertMany<\/code> statement that restructures each document and adds a calculated field, as shown in the following code:<\/p>\n<pre class=\"lang:none theme:none\">db.employees.updateMany(\n  { },\n  [\n    { $set: { \"position\": { \"title\": \"$title\", \"department\": \"$department\" } } },\n    { $set: { \"position.division\": { $switch: {\n      branches: [\n        { case: { $eq: [ \"$position.department\", \"Development\"] }, then: \"Eastern\" },\n        { case: { $eq: [ \"$position.department\", \"IT Services\"] }, then: \"Eastern\" },\n        { case: { $eq: [ \"$position.department\", \"Marketing\"] }, then: \"Western\" },\n        { case: { $eq: [ \"$position.department\", \"Sales\"] }, then: \"Western\" }\n      ],\n      default: \"Central\" } } } },\n    { $unset: [ \"title\", \"department\" ] }\n  ]\n);<\/pre>\n<p>The statement begins by defining the <code><em>filter<\/em><\/code> element as an empty document, which means that the update will be applied to all documents in the collection. The <code><em>filter<\/em><\/code> element is followed by an <code><em>update<\/em><\/code> element that defines an aggregation pipeline, as indicated by the square brackets. The pipeline includes the following three stages:<\/p>\n<ul>\n<li>The first <code>$set<\/code> stage (which is an alias for <code>$addFields<\/code>) adds a field named <code>position<\/code>. The field\u2019s value is an embedded document that contains the <code>title<\/code> and <code>department<\/code> subfields. The original <code>title<\/code> and <code>department<\/code> fields provide the values for the new subfields. This is done by referencing the original fields and preceding their names with a dollar sign.<\/li>\n<li>The second <code>$set<\/code> stage creates a subfield named <code>division<\/code> within the <code>position<\/code> field. The value of the subfield is determined by the <code>$switch<\/code> operator, which is used to create a conditional <code>case<\/code> expression. The expression defines the <code>branches<\/code> array and its four embedded documents. Each document uses the <code>case<\/code> operator to specify a value for the <code>division<\/code> subfield, based on a value in the <code>department<\/code> subfield. For example, the first embedded document specifies that the <code>division<\/code> subfield should be assigned the value <code>Eastern<\/code> if the <code>department<\/code> value is <code>Development<\/code>. The <code>branches<\/code> array is then followed by a <code>default<\/code> element that designates <code>Central<\/code> as the default value if no conditions are met.<\/li>\n<li>The final <code>$unset<\/code> stage specifies that the original <code>title<\/code> and <code>department<\/code> fields should be removed from each document. These fields are no longer needed because their values have been reassigned to the <code>position<\/code> subfields in the first <code>$set<\/code> stage.<\/li>\n<\/ul>\n<p>After you define you\u2019re statement, you can run it in MongoDB Shell and view the results on the <strong>Documents<\/strong> tab. The following figure shows the collection\u2019s documents after they\u2019ve been updated and the tab refreshed.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"794\" height=\"966\" class=\"wp-image-101964\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2024\/03\/word-image-101954-10.png\" \/><\/p>\n<p>As you can see, each document now contains the <code>position<\/code> field and its value, which is an embedded document. The embedded document includes the original <code>title<\/code> and <code>department<\/code> fields, along with the new <code>division<\/code> field.<\/p>\n<p>Although we were working with very simple documents for this example, it should still give you a sense of how useful it might be to include an aggregation pipeline in your <code>updateOne<\/code> and <code>updateMany<\/code> statements, despite having only three stages to work with.<\/p>\n<h2>Getting started with MongoDB updates<\/h2>\n<p>The ability to update data is one of the core skills you should have when working with MongoDB. To this end, the <code>updateOne<\/code> and <code>updateMany<\/code> methods provide a good place to start learning how to modify data. However, they\u2019re not the only methods available. For example, MongoDB also supports the <code>replaceOne<\/code>, <code>findOneAndReplace<\/code>, <code>findOneAndUpdate<\/code>, and <code>findAndModify<\/code> methods, any of which you might find useful at times. In addition, you can update data directly in the Compass GUI by modifying a document\u2019s individual values.<\/p>\n<p>Despite the various options available in MongoDB for updating data, the <code>updateOne<\/code> and <code>updateMany<\/code> methods will go a long way in helping you get started with modifying data. You might find it useful to check out the MongoDB documentation that covers these methods, as well as other methods for updating data. When it comes to modifying data, however, you must proceed cautiously to ensure you don\u2019t make incorrect changes, especially in a production environment. The better you understand how to update data in a MongoDB database, the less likely you are to inadvertently wipe out an entire collection of documents.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>In the previous articles this series, I demonstrated various ways to retrieve document data from a MongoDB database, using both MongoDB Shell and MongoDB Compass. In this article, my focus shifts from retrieving data to updating data, which is an essential skill to have when working with MongoDB. Whether you access the data directly in&#8230;&hellip;<\/p>\n","protected":false},"author":221841,"featured_media":104584,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[53,159161],"tags":[5618,159226],"coauthors":[6779],"class_list":["post-101954","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-featured","category-mongodb","tag-mongodb","tag-mongodbseriesrobertsheldon"],"acf":[],"_links":{"self":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts\/101954","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/users\/221841"}],"replies":[{"embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/comments?post=101954"}],"version-history":[{"count":4,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts\/101954\/revisions"}],"predecessor-version":[{"id":103098,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts\/101954\/revisions\/103098"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/media\/104584"}],"wp:attachment":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/media?parent=101954"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/categories?post=101954"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/tags?post=101954"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/coauthors?post=101954"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}