This article is part of Robert Sheldon's continuing series on Mongo DB. To see all of the items in the series, click here.
So far in this series, we’ve looked at different ways that you can add, retrieve, and update documents in a MongoDB collection. This article continues that discussion by explaining how to use MongoDB Shell to delete documents from a collection. Once you know how to delete documents, you’ll have the foundation you’ll need to perform the basic create, read, update, and delete (CRUD) operations in MongoDB, assuming you’ve been following along in this series. From this foundation, you can start moving on to more advance CRUD operations.
As with other aspects of MongoDB, the platform supports multiple ways to delete documents. In this article, I focus on how to use the deleteOne
and deleteMany
methods, which are available to the collection object, similar to what you saw with the updateOne
and updateMany
methods. As their names suggest, the deleteOne
method can delete only one document at a time, while the deleteMany
method can delete any number of documents in a collection.
The examples in this article are specific to MongoDB Shell, rather than applying to a programming language such as PHP or Python. The syntax tends to vary from one environment to the next, so you have to treat them individually, although the basic concepts are the same.
The deleteOne
and deleteMany
methods are fairly straightforward. Most of the work is in the filter, which is defined as one of the method’s arguments. The filter determines which documents in the collection to delete. As you work through this article, you’ll get a better sense of how the filter works and how to create filters to meet your needs.
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. The examples in this article use the hr
database and candidates
collection in that database to demonstrate various way to delete data. As we work through the article, I’ll explain how to set those up and add documents to them.
Deleting documents in a MongoDB collection
The deleteOne
and deleteMany
methods are two of the most common techniques used to delete documents from a MongoDB collection. You can use either method in MongoDB Shell by creating a statement that references the collection object and then calls the method. The statement syntax is essentially the same for either method, except for the method name. For example, the following syntax shows the elements that make up a deleteOne
statement:
1 |
db.collection.deleteOne( { filter }, { options } ); |
As the syntax indicates, the statement consists of the following components:
- db. System variable for referencing the current database and accessing the properties and methods available to the database object.
- collection. Placeholder for the target collection. For this article, we will be using the
candidates
collection. - deleteOne. A method available to the collection object for deleting a single document in the specified collection.
- filter. Placeholder for the selection criteria that determine which document to delete. This is similar to the filter used in a
find
statement. Iffilter
returns more than one document, MongoDB deletes only to the first document returned from the collection. An empty document ({}
) means thatfilter
returns all documents in the collection, although MongoDB still deletes only to the first returned document. - options. Placeholder for one or more optional settings that can be included in an
deleteOne
statement to better refine the query.
A statement that is based on an deleteMany
method works much the same way as the deleteOne
method. The only variation in the basic syntax is the method name:
1 |
db.<em>collection</em>.deleteMany( { <em>filter</em> }, { <em>options</em> } ); |
The main difference between the deleteOne
and deleteMany
methods, other than their names, is the filter
element. With the deleteOne
method, only the first document returned from the collection is deleted, no matter how many documents that filter
returns. With the deleteMany
method, all documents that filter
returns are deleted. With that in mind, let’s take a look at some examples.
Deleting a single document
For the examples in this article, we’ll be using the version of MongoDB Shell that’s embedded in the MongoDB Compass GUI. In this way, we can view our results in the main Compass interface as we delete data in MongoDB Shell, making it easier to visually verify our deletions. We’ll also be using the hr
database, which might already exist on your system if you tried out the examples in the previous article in this series.
When working in MongoDB Shell, you have to switch the database context to the database you want to target. For this, you need to issue a use
command, as you’ve seen in previous articles:
1 |
use hr; |
You can use this command whether or not the database already exists. In this case, the command switches the database context to hr
. If the database doesn’t exist, MongoDB automatically creates it. However, the database will not show up in the Compass GUI until you’ve added your first collection.
After you switch the database context, you can use the createCollection
method to add a collection to the active database. To create the candidates
collection, you should run the following createCollection
statement:
1 |
db.createCollection("candidates"); |
Once you’ve created the collection, you can use the insertMany
method to add documents to that collection. For the first set of examples in this article, you should run the following insertMany
statement in MongoDB Shell:
1 2 3 4 5 6 7 8 |
db.candidates.insertMany([ { "_id": 101, "name": "Drew", "position": "Senior Developer", "dept": "R&D" }, { "_id": 102, "name": "Parker", "position": "Data Scientist", "dept": "R&D" }, { "_id": 103, "name": "Harper", "position": "Marketing Manager", "dept": "Marketing" }, { "_id": 104, "name": "Darcy", "position": "Senior Developer", "dept": "R&D" }, { "_id": 105, "name": "Carey", "position": "SEO specialist", "dept": "Marketing" }, { "_id": 106, "name": "Avery", "position": "Network Admin", "dept": "IT" } ]); |
The insertMany
statement adds six simple documents to the collection. After you’ve run the statement, open the candidates
collection in the Documents tab of the main window. The tab should display the documents you just created, as shown in the following figure.
Now that we’ve added the documents, let’s look at how we go about deleting them, starting with the deleteOne
method. In its simplest form, the method requires no arguments other than an empty document, as in the following example:
1 |
db.candidates.deleteOne({}); |
As I pointed out earlier, the deleteOne
method deletes only one document no matter how many are returned by the filter. In this case, no filter is defined, so all documents in the collection are returned, although only the first one is deleted. When you run the statement, MongoDB Shell returns the following message, which confirms that a single document has been removed:
1 2 3 4 |
{ acknowledged: true, deletedCount: 1 } |
Next, go to the Documents tab of the main Compass window and click the refresh button in the tab’s upper right corner. The tab should now display only five documents, rather than the original six. The first document in the collection had an _id
value of 101
, but that document has been removed, as shown in the following figure.
In most cases, you’ll define a filter when using the deleteOne
method, rather than passing in an empty document. For example, if you want to specifically delete the document with an _id
value of 102
, you can use the following statement:
1 |
db.candidates.deleteOne({ "_id": 102 }); |
The deleteOne
method now includes a filter, which specifies the name of the field, _id
, followed by the target value, 102
. A colon separates the field name from the value. When you run the statement, MongoDB returns only this document, which is then deleted. The statement also returns the same message as the previous example, confirming that only one document was deleted.
Because the filter specifically states which document to delete, MongoDB will remove only that one, if it exists. If it does not exist, MongoDB returns a message indicating that no documents have been removed.
Deleting multiple documents
If you want to delete more than one document at a time, you should use the deleteMany
method, rather than deleteOne
. The two methods work the same, in terms of how they filter documents, so once you understand how to use one, you should have no problem using the other. For example, the following statement uses the deleteMany
method to remove all documents whose dept
field value is Marketing
:
1 |
db.candidates.deleteMany({ "dept": "Marketing" }); |
As in the previous example, the filter specifies a field name (in this case, dept
), followed by the target value (Marketing
). Only two documents match this search criteria, one with an _id
value of 103
and the other with an _id
value of 105
. These are the two documents that are deleted.
As with the deleteOne
method, you do not have to define a filter when using the deleteMany
method. You can simply pass in an empty document, as in the following example:
1 |
db.candidates.deleteMany({}); |
Although this is a quick and easy way to delete all the documents in a collection, you must be extremely cautious when taking this approach so you don’t inadvertently wipe out an entire collection in a single blow.
Deleting documents based on embedded fields
A collection’s documents often contain embedded documents. In some cases, you might want to delete documents based on one of the embedded values. The type of deletion works much the same as any other type of deletions, except that you need to reference the embedded field in a specific way.
Before I demonstrate how this works, make sure there are no documents left in the candidates
collection. If you followed along with the examples in the previous section, the collection should now be empty. However, if any of the original documents still remain, you should first run the following deleteMany
statement:
1 |
db.candidates.deleteMany({}); |
Once the collection is empty, you can run the following insertMany
statement to add the next set of sample data, which we’ll use for the remaining examples in this article:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 |
db.candidates.insertMany([ { "_id": 101, "name": "Drew", "position": { "title": "Senior Developer", "dept": "R&D", "skills": [ "Java", "SQL", "Python", "PHP" ], "yrs_exp": 18 } }, { "_id": 102, "name": "Parker", "position": { "title": "Data Scientist", "dept": "R&D", "yrs_exp": 14 } }, { "_id": 103, "name": "Harper", "position": { "title": "Marketing Manager", "dept": "Marketing", "yrs_exp": 22 } }, { "_id": 104, "name": "Darcy", "position": { "title": "Senior Developer", "dept": "R&D", "skills": [ "Java", "Csharp", "Python", "R" ], "yrs_exp": 6 } }, { "_id": 105, "name": "Carey", "position": { "title": "SEO Specialist", "dept": "Marketing", "yrs_exp": 7 } }, { "_id": 106, "name": "Avery", "position": { "title": "Network Admin", "dept": "IT", "yrs_exp": 11 } }, { "_id": 107, "name": "Avery", "position": { "title": "Developer", "dept": "R&D", "skills": [ "Haskell", "Fortran", "Smalltalk", "COBOL" ], "yrs_exp": 8 } } ]); |
The insertMany
statement adds seven documents. Each one contains the position
field, whose value is an embedded document. After you add the documents, you can view them on the Documents tab of the main Compass window, as you did before. Don’t forget to click the refresh button. The following figure shows the first four new documents, with the position
field expanded in the first document.
Notice that the embedded document includes the dept
field. Suppose you want to delete the documents in the collection that have a dept
value of Marketing
. As you saw in previous articles in this series, you can reference the fields in an embedded document by qualifying the field name with the parent field. In this case, you would reference the dept
field by first specifying the position
field, followed by a period, and then by dept
, as in position.dept
.
Before I demonstrate how to delete documents based on an embedded field, I first want to point out that you can use the find
method to verify what documents will be deleted before you actually delete them. The filter in the find
method works just like the deleteOne
or deleteMany
filter, so it provides a handy way of verifying your actions before carrying them out. For example, the following find
statement returns all documents with a position.dept
value of Marketing
:
1 |
db.candidates.find({ "position.dept": "Marketing" }); |
The statement returns two documents, one with an _id
value of 103
and the other with an _id
value of 105
. The following figure shows the results as they appear in MongoDB Shell.
Once you’ve verified which documents will be deleted, you can then use the same filter in your deleteMany
statement, as in the following example:
1 |
db.candidates.deleteMany({ "position.dept": "Marketing" }); |
Not surprisingly, the statement deletes the same two documents. Using a find
statement in this way is optional, of course, but you might find it useful at times, especially when you’re dealing with complex documents or statement filters.
Deleting documents based on multiple search criteria
Up to this point, the filters in the example statements included only one search condition. However, you might find it necessary to specify multiple conditions in your filter. To do so, you include all the conditions within the same set of curly brackets and then use a comma to separate them. For example, the following deleteOne
statement includes two search conditions in its filter:
1 |
db.candidates.deleteOne({ "name": "Avery", "position.dept": "IT" }); |
The first search condition specifies that the name
field must contain the value Avery
, and the second search condition specifies that the position.dept
field much contain the value IT
. For a document to be deleted, it must meet both search conditions. Only one document in the collection meets these two conditions: the one with an _id
value of 106
.
You can also use comparison operators when defining your method’s filters. For instance, the following deleteMany
statement uses the $lt
(less than) comparison operator:
1 2 3 |
db.candidates.deleteMany({ "position.title": "Senior Developer", "position.yrs_exp": { $lt: 10 } }); |
The statement’s first search condition specifies that the position.title
value must be Senior
Developer
. The statement’s second search condition specifies that the position.yrs_exp
value must be less than 10
. As in the previous example, both conditions must be met for a document to be deleted. In this case, only the document with an _id
value of 104
satisfies both conditions.
You might have noticed that in some documents the position
field includes the skills
subfield, which is an array of string values. When deleting documents, you can specify array values as part of your method’s filter, as in the following example:
1 2 3 |
db.candidates.deleteMany({ "position.dept": "R&D", "position.skills": { $all: [ "Haskell", "Fortran" ] } }); |
The statement’s filter includes two search conditions. The first specifies that the position.dept
value should be R&D
, and the second specifies that the position.skills
array should contain the values Haskell
and Fortran
. The $all
operator tells MongoDB that the array must include both values. It can also contain other values, but it must contain Haskell
and Fortran
for the document to be returned (and subsequently deleted). In this case, only one document meets both criteria, the one with an _id
value of 107
.
Specifying an option when deleting documents
The deleteOne
and deleteMany
methods also support several options that you can include when deleting documents from a collection. Although a discussion of each option is beyond the scope of this article, I want to at least demonstrate how to specify an option in case the need arises.
One of the options is collation
, which lets you define language-specific rules for string comparisons. For example, the following deleteOne
statement uses the collation
option to specify the locale
setting, which is associated with a specific language, and the strength
setting, which determines the level of comparison to perform:
1 2 3 4 |
db.candidates.deleteOne( { "name": "Drew", "position.dept": "R&D" }, { collation: { locale: "en", strength: 1 } } ); |
In this case, the value assigned to locale
is en
, the setting used for basic English. The value assigned to strength
is 1
. This means that string comparisons are carried out only on the base characters and are not concerned with differences such as diacritics and case.
When specifying options in a deleteOne
or deleteMany
statement, you must enclose them in a second set of curly brackets. The options come after the filter, with a comma separating the two. If you specify more than one option, you must separate them with a comma as well.
The filter in this example specifies that the name
value must be Drew
and the position.dept
value must be R&D
. The only document to meet these search conditions is the one with an _id
value of 101
.
Getting started with deleting documents in MongoDB
The deleteOne
and deleteMany
methods help to complete the picture on how to perform CRUD operations in a MongoDB database, at least in terms of carrying out those operations in MongoDB Shell. In the next article, I’ll explain how to use the Compass GUI to perform many of these operations, and later in the series, we’ll look at how to perform them in a programming language such as Python. In the meantime, you might want to read the MongoDB documentation on the deleteOne and deleteMany methods to get a more complete picture of how they work.
Load comments