Learn

In MongoDB, sometimes we may want to update a document but also return the document we modified. The .findAndModify() method modifies and returns a single document. By default, the document it returns does not include the modifications made on the update. This method can be particularly useful if we want to see (or use) the state of an updated document after we perform an update operation. This method also has a lot of flexible optional parameters that aren’t available in other methods.

Let’s take a look at the syntax of the .findAndModify() method below:

db.<collection>.findAndModify({ query: <document>, update: <document>, new: <boolean>, upsert: <boolean>, ... });

Note that there are four commonly used fields:

  1. query: Defines the selection criteria for which record needs modification.
  2. update: A document that specifies the fields we want to update and the changes we want to make to them.
  3. new: When true, this field returns the modified document rather than the original.
  4. upsert: Creates a new document if the selection criteria fails to match a document.

Note: In addition to these fields, the .findAndModify() method accepts many other options. We will not be covering them here, but more details can be found in the documentation for the .findAndModify() method.

With this method, there are a lot of scenarios that can occur. First, let’s consider a collection called foodTrucks containing the following document:

{ _id: ObjectId(...), name: "Criff Dogs", address: "15 Bedford Ave", shutdown: false }, { _id: ObjectId(...), name: "Sals Pizza", address: "249 Otter Place", shutdown: false }

The first scenario we can observe is if we wanted to update a document and see the updated document state pre-modification (before it was changed). This is the default behavior of the method. So, if we were to change the shutdown property of the document above with the name "Criff Dogs", we can run the following command:

db.foodTrucks.findAndModify({ query: { name: "Criff Dogs" }, update: { shutdown: true } });

The output of this method would be the document before it was modified. Notice the shutdown field is still false, even though we changed it to true:

//Output { _id: ObjectId(...), name: "Criff Dogs", address: "15 Bedford Ave", shutdown: false }

The next scenario is similar but would use the new field to return a different output. If we ran the following query:

db.foodTrucks.findAndModify({ query: { name: "Criff Dogs" }, update: { shutdown: true }, new: true });

We would be able to see the new modified document as the output. Notice the value in the output for the shutdown field is true:

//Output { _id: ObjectId(...), name: "Sals Pizza", address: "249 Otter Place", shutdown: true }

Lastly, we can use the upsert field to be able to add documents if they do not currently exist in the database. So if we ran the following command:

db.foodTrucks.findAndModify({ query: { name: "Ben and Jerry", address: "17 Cliff Pl" }, update: { shutdown: false }, new: true, upsert: true });

MongoDB would then search the collection foodTrucks based on the query argument, and if it didn’t find a match, it would create the document. So our new food truck would be added to the collection, and our return output would be:

//Output { _id: ObjectId(...), name: "Ben and Jerry", address: "17 Cliff Pl", shutdown: false }

We might notice that .updateOne() and .findAndModify() behave quite similarly. Both will update a document in our database or create one if it doesn’t exist. So what are the main differences? Well, .findAndModify() returns the document that you modify, whereas .updateOne() does not. Moreover, .findAndModify() allows us to specify whether we want to return the old or new (modified version) of the updated document with the use of the new parameter.

Let’s practice using the findAndModify() method with our restaurants collection!

Instructions

1.

Connect to the restaurants database. Then use the .findOne() method to query the listingsAndReviews collection for the document with the name of "Jolie Cantina". Observe the document you find!

2.

Use the findAndModify() method to change value of the "cuisine" field for restaurant named "Jolie Cantina" from "French" to "American". Make sure the output returns the new modified document.

3.

We want to ensure that a restaurant named Jacobs Bagels has the correct information in our restaurants database. We are unsure if the restaurant is currently in the listingsAndReviews collection. Use .findAndModify() to add a the document (if it does not exist) to the listingsAndReviews collection with the following data:

{ name: "Jacobs Bagels", cuisine: "Jewish/Kosher", borough: "Brooklyn" }

Make sure to return the newly updated (or created) document.

Take this course for free

Mini Info Outline Icon
By signing up for Codecademy, you agree to Codecademy's Terms of Service & Privacy Policy.

Or sign up using:

Already have an account?