MongoDB - Update Query

The Mongo engine provides the update() method the ability to allow an existing document, or many documents, to be updated within a collection.

The update() method accepts up to 3 documents as it's query parameters. Those query parameters are:

  • an update condition document to match the documents to update
  • an update operations document to specify the type of query to perform
  • an options document

You use the same syntax and document query structure as the query conditions.

It should be noted, that, by default, the update() method only updates a single document.

In order to update multiple documents, you should use the multi option.

Update Fields in a Document

To change a field value in a MongoDB document collection, the Mongo engine provides update operators to modify field values. Update operators, like $set will create the field if the field does not already exist.

Examples:

Update field values

connecting to: test  
> db.people.update(
  {
    'name' : 'Craig Derington',
    {
      $set : {
        'role' : 'admin',
        'email' : 'email',
        'phone_number' : 'phone-number',        
      },
      $currentDate : {
        lastModified : true
      }
    }
  });
WriteResult({ 'nMatched' : 1, 'nUpserted' : 0, 'nModified' : 1})  

The update operation returns a WriteResult document object that displays the status of the MongoDB write operation. You'll also notice the MongoDB shell returned a success message for our update query.

The nMatched field shows the number of existing documents in the collection that matched the query for for update, and nModified specifies the number of existing documents in the collection that were modified as a result of the query.

Update an Embedded Data Field

To update a field within an embedded document in our people collection, such as the address field, we need to use dot notation to indicate the nesting level order for our update operation to perform.

In this example, our embedded document is address and our field is street name.

When utilizing dot notation, you should enclose the entire dotted field names in double or single quotes.

connecting to: test  
> db.people.update(
  { 'name' : 'Craig Derington'},
  { $set : { 'address.streetname' : '1041 NW 16th Street'    
    }
  }
);
WriteResult({ 'nMatched' : 1, 'nUpserted' : 0, 'nModified' : 1 })  

Our update query returned a write result document object that displays the status of our update query operation. In this example, our status returned a success message and shows we matched 1 and modified 1 document in the people collection.

Update Multiple Documents in a Collection

As I mentioned above, MongoDB, by default, only updates a single document matching the query parameters. It will only update the first document it finds, in the natural order as found on the disk. Yes, the actual physical device storing the data. In order to update multiple documents, we must pass the multi option to the update() method.

connecting to test  
> db.people.update(
  { 'role' : 'admin' },
  { $set : { role : 'moderator'},
    $currentDate : { lastModified : true }
  },
  { multi : true }
);
WriteResult({ 'nMatched' : 12, 'nUpserted' : 0, 'nModified' : 12 })  

The Mongo shell displays the expected result of our update query. The 12 admins roles were changed to moderator simply by adding the multi equals true option in the document structure.

Replace an Existing Document with a New Document in a Collection

To replace the contents of an entire document with the content of a new query (except for the id field), simply pass the update query an entirely new document as the second argument to the update() method.

The replacement document can have completely different fields from the original document. In the replacement document, you can omit the id field since the id field is immutable. If you don't include the id field, it must be the same value as the existing document id value.

To replace an existing document in our people collection, we write our query as follows.

connecting to: test  
> db.people.update(
    { 'name' : 'Craig Derington' },
    {
      'name' : 'James Sockets',
      'role' : 'admin',
      'email' : 'james@sockets.net',
      'phone_number' : 'phone-number',
      'address' : {
        'street_number' : '671',
        'stree_name' : 'Grackle Drive',
        'city' : 'Casselberry',
        'state' : 'FL',
        'zip_code' : '32707'
      }
    }
);
WriteResult({ 'nMatched' : 1, 'nUpserted' : 0, 'nModified' : 1 })  

The write result shows us the success message from the update operation.

The MongoDB Upsert Option

In my opinion, this is one of the coolest features of Non-Rel databases. Having spent many, many years writing queries in the structured query language (SQL), it's super nice to write queries that, when no records match the query parameters, and upsert is set to true, instead of an update operation, a new document is added to our collection.

For example:

connecting to: test  
> db.people.update(
  { 'name' : 'James Rockets' },
  {
    'name' : 'James Rockets',
    'address' : {
      'street_number' : '1600', 'street_name' : 'W Penn St.',
      'city' : 'Washington',
      'state' : 'DC',
      'zip_code' : '20001'
    },
    'role' : 'moderator',
    'email' : 'jrocket@gmail.com',
    'phone_number' : 'phone-number',
  },
  { upsert : true }
);
WriteResult({ 'nMatched' : 0, 'nUpserted' : 1, 'nModified' : 0, '_id' : ObjectId('54678e...') })  

The status of the update operation shows a write result displaying a success message and 1 document was upserted.

Notice the upsert message also returns the ObjectId of the newly added document.

In the next installment of my Intro to MongoDB, I am going to write about Deleting documents in a collection, the delete() method and the delete method's parameters.

Craig Derington

Espousing the virtues of Secular Humanism, Libertarianism, Free and Open Source Software, Linux, Ubuntu, Terminal Multiplexing, Docker, Python, Flask, Django, Go, MySQL, PostgreSQL, MongoDB and Git.

comments powered by Disqus