MongoDB: How to remove array elements matching a condition

Updated: February 3, 2024 By: Guest Contributor Post a comment

Introduction

Working with arrays in MongoDB can be a common but challenging task, especially when it comes to modifying array contents based on specific conditions. MongoDB provides various methods to manipulate arrays, such as adding new elements, updating existing ones, and of course, removing elements that match a given condition.

In this tutorial, we’ll explore how to remove elements from an array in a MongoDB document that match certain conditions. We’ll start with basic examples and gradually move to more advanced use cases, providing code examples and expected outputs.

Understanding MongoDB Arrays

Before we jump into removal operations, it’s important to understand how arrays are structured within MongoDB documents. An array is simply a list of values that can contain elements of varying data types—strings, numbers, objects, or even other arrays. In MongoDB, arrays are versatile, allowing storage of multiple values, which can be easily queried and modified when required.

Here’s a sample document illustrating an array in a MongoDB collection:

{
  _id: ObjectId("606d0b7b4141b6774f9167f1"),
  title: "Favorite Fruits",
  fruits: ["apple", "banana", "cherry", "date"]
}

Basic Array Element Removal

The simplest way to remove elements from an array in MongoDB is using the $pull operator. It allows removal of all instances of a value from an array that match specified conditions. Here’s how you can remove a single element:

db.collection.update(
  { _id: ObjectId("606d0b7b4141b6774f9167f1") },
  { $pull: { fruits: "banana" } }
);

The above code will remove all occurrences of “banana” from the fruits array in the document with the specified _id. The updated document will look like this:

{
  _id: ObjectId("606d0b7b4141b6774f9167f1"),
  title: "Favorite Fruits",
  fruits: ["apple", "cherry", "date"]
}

Removing Multiple Elements Matching a Condition

What if you want to remove multiple elements based on a certain condition? The $pull operator also accepts $in to remove elements that match any of the values specified in an array:

db.collection.update(
  { _id: ObjectId("606d0b7b4141b6774f9167f1") },
  { $pull: { fruits: { $in: ["banana", "date"] } } }
);

After this operation, both “banana” and “date” will be removed from the fruits array. The resulting document will be:

{
  _id: ObjectId("606d0b7b4141b6774f9167f1"),
  title: "Favorite Fruits",
  fruits: ["apple", "cherry"]
}

Conditional Removal with Queries

Sometimes, you may want to remove array elements that match a more complex condition. The $pull operator allows for this by supporting query-like conditions inside the removal criteria. Let’s remove fruits that start with a ‘c’:

db.collection.update(
  { _id: ObjectId("606d0b7b4141b6774f9167f1") },
  { $pull: { fruits: /^c/ } }
);

Now, all fruits starting with the letter ‘c’ are removed from the array:

{
  _id: ObjectId("606d0b7b4141b6774f9167f1"),
  title: "Favorite Fruits",
  fruits: ["apple", "date"]
}

Using $pull with Embedded Documents

Arrays containing embedded documents are common in MongoDB. Let’s say we have the following document:

{
  _id: ObjectId("506d0b7b41413767bf9301e1"),
  title: "Film Collection",
  films: [
    { title: "Inception", year: 2010 },
    { title: "The Matrix", year: 1999 },
    { title: "Interstellar", year: 2014 }
  ]
}

To remove a film released before the year 2000, we can use the following query with $pull:

db.collection.update(
  { _id: ObjectId("506d0b7b41413767bf9301e1") },
  { $pull: { films: { year: { $lt: 2000 } } } }
);

As a result, “The Matrix” is removed from the films array since it was released in 1999:

{
  _id: ObjectId("506d0b7b41413767bf9301e1"),
  title: "Film Collection",
  films: [
    { title: "Inception", year: 2010 },
    { title: "Interstellar", year: 2014 }
  ]
}

Advanced Removal Using $pull with $elemMatch

For more complex conditions involving multiple fields in embedded documents, $elemMatch comes into play:

db.collection.update(
  { _id: ObjectId("506d0b7b41413767bf9301e1") },
  { $pull: { films: { $elemMatch: { year: { $gt: 2010 }, title: /^I/ } } } }
);

This operation will remove films that were released after 2010 and have a title starting with the letter ‘I’. In this case, “Interstellar” will be removed, and we’ll be left with the following document:

{
  _id: ObjectId("506d0b7b41413767bf9301e1"),
  title: "Film Collection",
  films: [
    { title: "Inception", year: 2010 }
  ]
}

Conclusion

Throughout this tutorial, we’ve examined how to leverage MongoDB’s powerful $pull operator to remove array elements that match a variety of conditions. By progressing from basic to more advanced examples, we have demonstrated the flexibility in handling array modifications within MongoDB documents. Remember to test queries in a development environment and use write concern to avoid data inconsistency in production.