Open In App

How to Filter Array in Subdocument with MongoDB?

Last Updated : 17 Apr, 2024
Improve
Improve
Like Article
Like
Save
Share
Report

In MongoDB, working with arrays within subdocuments is a common requirement in many applications. Filtering and manipulating arrays efficiently can significantly enhance the flexibility and enhance our queries.

In this article, we’ll explore how to filter arrays within subdocuments in MongoDB by covering essential concepts and providing detailed examples with outputs to understand these techniques effectively.

Understanding Subdocuments in MongoDB

  • A subdocument in MongoDB is a document embedded within another document. It allows for a hierarchical structure and enables the storage of complex data models within a single MongoDB document.
  • Just like a regular document, a subdocument consists of field-value pairs. These fields can contain values of various types, including strings, numbers, arrays or even other subdocuments.
  • MongoDB allows arrays of subdocuments which means a single field can contain multiple subdocuments. It is useful for storing related data that belong together.
  • MongoDB provides atomic operations for updating individual fields within a subdocument. This allows for efficient updates without needing to retrieve and replace the entire document.
  • MongoDB supports querying based on fields within subdocuments. This allows for precise retrieval of documents that match specific criteria within their subdocuments.

Filtering Arrays in Subdocuments

Filtering arrays within subdocuments involves querying documents based on conditions specified for elements within the array. MongoDB provides several operators and methods to perform array filtering efficiently.

Let’s set up an Environment:

To understand How to filter array in subdocument with MongoDB we need a collection and some documents on which we will perform various operations and queries. Here we will consider a collection called users which contains information shown below:

{
"_id": ObjectId("60f9d7ac345b7c9df348a86f"),
"name": "Bob",
"tasks": [
{ "title": "Task 1", "completed": true },
{ "title": "Task 2", "completed": true },
{ "title": "Task 3", "completed": false }
]
},
{
"_id": ObjectId("60f9d7ac345b7c9df348a870"),
"name": "Charlie",
"tasks": [
{ "title": "Task 1", "completed": false },
{ "title": "Task 2", "completed": false }
]
},
{
"_id": ObjectId("60f9d7ac345b7c9df348a871"),
"name": "David",
"tasks": [
{ "title": "Task 1", "completed": true },
{ "title": "Task 2", "completed": true },
{ "title": "Task 3", "completed": true },
{ "title": "Task 4", "completed": false }
]
}

In this example:

  • Each document represents a user with a name field.
  • The “tasks” field is an array of subdocuments containing task details such as title and completion status.

Example 1: Filtering Completed Tasks

We only want to retrieve users who have at least one completed task. We can achieve this using the $elemMatch projection operator:

db.users.find({ tasks: { $elemMatch: { completed: true } } })

Output:

[
{
"_id": ObjectId("60f9d7ac345b7c9df348a86e"),
"name": "Alice",
"tasks": [
{ "title": "Task 1", "completed": true },
{ "title": "Task 2", "completed": false },
{ "title": "Task 3", "completed": true }
]
},
{
"_id": ObjectId("60f9d7ac345b7c9df348a86f"),
"name": "Bob",
"tasks": [
{ "title": "Task 1", "completed": true },
{ "title": "Task 2", "completed": true },
{ "title": "Task 3", "completed": false }
]
},
{
"_id": ObjectId("60f9d7ac345b7c9df348a871"),
"name": "David",
"tasks": [
{ "title": "Task 1", "completed": true },
{ "title": "Task 2", "completed": true },
{ "title": "Task 3", "completed": true },
{ "title": "Task 4", "completed": false }
]
}
]

This query will return documents where at least one task within the “tasks” array has the “completed” field set to true.

Example 2: Filtering Tasks by Title

Suppose we want to filter tasks based on their title within the “tasks” array. We can use the dot notation to access fields within subdocuments and apply query conditions accordingly:

db.users.find({ "tasks.title": "Task 2" })

Output:

[
{
_id: ObjectId('60f9d7ac345b7c9df348a86f'),
name: 'Bob',
tasks: [
{ title: 'Task 1', completed: true },
{ title: 'Task 2', completed: true },
{ title: 'Task 3', completed: false }
]
},
{
_id: ObjectId('60f9d7ac345b7c9df348a870'),
name: 'Charlie',
tasks: [
{ title: 'Task 1', completed: false },
{ title: 'Task 2', completed: false }
]
},
{
_id: ObjectId('60f9d7ac345b7c9df348a871'),
name: 'David',
tasks: [
{ title: 'Task 1', completed: true },
{ title: 'Task 2', completed: true },
{ title: 'Task 3', completed: true },
{ title: 'Task 4', completed: false }
]
}
]

This query will return documents where at least one task within the “tasks” array has the title “Task 2”.

Example 3: Filtering Completed Tasks Count

If we want to filter users based on the count of completed tasks, we can use the $size operator to match arrays with a specific number of elements:

db.users.find({ tasks: { $size: 2 } })

Output

[
{
_id: ObjectId('60f9d7ac345b7c9df348a870'),
name: 'Charlie',
tasks: [
{ title: 'Task 1', completed: false },
{ title: 'Task 2', completed: false }
]
}
]

This query will return documents where the “tasks” array contains exactly two elements.

Conclusion

Overall, Filtering arrays within subdocuments in MongoDB opens up a wide range of possibilities for querying and manipulating complex data structures. By understanding the array filtering operators and methods provided by MongoDB, developers can create efficient and powerful queries tailored to their specific use cases. In this article, we explored how to filter arrays within subdocuments using practical examples and outputs to illustrate these concepts clearly for beginners. As you continue to work with MongoDB, consider the structure of your data and leverage array filtering techniques to build robust and flexible database queries.



Like Article
Suggest improvement
Previous
Next
Share your thoughts in the comments

Similar Reads